Home » Releases » PHP 8.5 »

PHP 8.5 Code Comparisons

Explore PHP 8.5

URI Extension

The new always-available URI extension provides APIs to securely parse and modify URIs and URLs according to the RFC 3986 and the WHATWG URL standards. Powered by the uriparser (RFC 3986) and Lexbor (WHATWG URL) libraries. Learn more about the backstory of this feature in The PHP Foundation’s blog.
Before PHP 8.4
$components = parse_url('https://php.net/releases/8.4/en.php');

var_dump($components['host']);
// string(7) "php.net"
PHP 8.5 or Later
use Uri\Rfc3986\Uri;

$uri = new Uri('https://php.net/releases/8.5/en.php');

var_dump($uri->getHost());
// string(7) "php.net"

Pipe Operator

The pipe operator allows chaining function calls together without dealing with intermediary variables. This enables replacing many "nested calls" with a chain that can be read forwards, rather than inside-out. Learn more about the backstory of this feature in The PHP Foundation’s blog.
8.4 or Later
$title = ' PHP 8.5 Released ';

$slug = strtolower(
    str_replace('.', '',
        str_replace(' ', '-',
            trim($title)
        )
    )
);

var_dump($slug);
// string(15) "php-85-released"
PHP 8.5 or Later
$title = ' PHP 8.5 Released ';

$slug = $title
    |> trim(...)
    |> (fn($str) => str_replace(' ', '-', $str))
    |> (fn($str) => str_replace('.', '', $str))
    |> strtolower(...);

var_dump($slug);
// string(15) "php-85-released"

Clone With

Before PHP 8.5
readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}

    public function withAlpha(int $alpha): self
    {
        $values = get_object_vars($this);
        $values['alpha'] = $alpha;

        return new self(...$values);
    }
}

$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);
PHP 8.5 or Later
readonly class Color
{
    public function __construct(
        public int $red,
        public int $green,
        public int $blue,
        public int $alpha = 255,
    ) {}

    public function withAlpha(int $alpha): self
    {
        return clone($this, [
            'alpha' => $alpha,
        ]);
    }
}

$blue = new Color(79, 91, 147);
$transparentBlue = $blue->withAlpha(128);

#[\NoDiscard] Attribute

By adding the #[\NoDiscard] attribute to a function, PHP will check whether the returned value is consumed and emit a warning if it is not. This allows improving the safety of APIs where the returned value is important, but it's easy to forget using the return value by accident. The associated (void) cast can be used to indicate that a value is intentionally unused.
Before PHP 8.5
function getPhpVersion(): string
{
    return 'PHP 8.4';
}

getPhpVersion(); // No warning
PHP 8.5 or Later
#[\NoDiscard]
function getPhpVersion(): string
{
    return 'PHP 8.5';
}

getPhpVersion();
// Warning: The return value of function getPhpVersion() should
// either be used or intentionally ignored by casting it as (void)

Closures and First-Class Callables in Constant Expressions

Static closures and first-class callables can now be used in constant expressions. This includes attribute parameters, default values of properties and parameters, and constants.
Before PHP 8.5
final class PostsController
{
    #[AccessControl(
        new Expression('request.user === post.getAuthor()'),
    )]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}
PHP 8.5 or Later
final class PostsController
{
    #[AccessControl(static function (
        Request $request,
        Post $post,
    ): bool {
        return $request->user === $post->getAuthor();
    })]
    public function update(
        Request $request,
        Post $post,
    ): Response {
        // ...
    }
}

Array First / Last Functions

The `array_first()` and `array_last()` functions return the first or last value of an array, respectively. If the array is empty, null is returned (making it easy to compose with the ?? operator).
Before PHP 8.5
$lastEvent = $events === []
    ? null
    : $events[array_key_last($events)];
PHP 8.5 or Later
$lastEvent = array_last($events);

Persistent cURL Share Handles

Handles can now be persisted across multiple PHP requests, avoiding the cost of repeated connection initialization to the same hosts.
Before PHP 8.5
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);

curl_exec($ch);
PHP 8.5 or Later
$sh = curl_share_init_persistent([
    CURL_LOCK_DATA_DNS,
    CURL_LOCK_DATA_CONNECT,
]);

$ch = curl_init('https://php.net/');
curl_setopt($ch, CURLOPT_SHARE, $sh);

// This may now reuse the connection from an earlier SAPI request
curl_exec($ch);