Released November 21, 2024. A major update of the PHP language featuring the new URI extension, support for modifying properties while cloning, the Pipe operator, performance improvements, bug fixes, and general cleanup.
What's New in PHP 8.5?
A new major version with powerful features, performance improvements, and much more.
Clone with
Support for modifying properties while cloning objects with a more concise syntax.
Pipe Operator
The Pipe operator provides a more readable way to chain function calls by passing the result of one expression as the first argument to the next function.
#[\NoDiscard] Attribute
The #[\NoDiscard] attribute ensures that the return value of a function is either used or intentionally ignored, helping prevent bugs where return values are accidentally ignored.
New URI Extension
RFC 3986 and WHATWG URL compliant API with new classes like Uri\Rfc3986\Uri and Uri\WhatWg\Url.
array_first() and array_last()
Simplified array element retrieval with new built-in functions for common operations.
Additional Enhancements
Property Promotion for final classes, Attributes for constants, #[\Override] for properties, and more.
Clone With
It is now possible to update properties during object cloning by passing an associative array with the updated values to the clone() function. This enables straight-forward support of the "with-er" pattern for readonly classes.
Before PHP 8.5
final readonly class PhpVersion {
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version): self
{
$newObject = clone $this;
$newObject->version = $version;
return $newObject;
}
}
$version = new PhpVersion();
var_dump($version->version);
// string(7) "PHP 8.4"
var_dump($version->withVersion('PHP 8.5')->version);
// Fatal error: Uncaught Error: Cannot modify readonly property PhpVersion::$version
PHP 8.5+
final readonly class PhpVersion {
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version): self
{
return clone($this, [
'version' => $version,
]);
}
}
$version = new PhpVersion();
var_dump($version->version);
// string(7) "PHP 8.4"
var_dump($version->withVersion('PHP 8.5')->version);
// string(7) "PHP 8.5"
var_dump($version->version);
// string(7) "PHP 8.4"
Pipe Operator
The Pipe operator provides a more readable way to chain function calls by passing the result of one expression as the first argument to the next function.
Before PHP 8.5
$input = ' Some kind of string. ';
$output = strtolower(
str_replace(['.', '/', '…'], '',
str_replace(' ', '-',
trim($input)
)
)
);
var_dump($output);
// string(19) "some-kind-of-string"
PHP 8.5+
$input = ' Some kind of string. ';
$output = $input
|> trim(...)
|> (fn($string) => str_replace(' ', '-', $string))
|> (fn($string) => str_replace(['.', '/', '…'], '', $string))
|> strtolower(...);
var_dump($output);
// string(19) "some-kind-of-string"
#[\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 to improve the safety of APIs where the returned value is important, but where it is easy to forget using the return value by accident.
Before PHP 8.5
function getPhpVersion(): string
{
return 'PHP 8.4';
}
getPhpVersion(); // No Errors
PHP 8.5+
#[\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)
New URI Extension
As an always-available part of PHP's standard library the new URI extension provides APIs to parse and modify URIs and URLs according to the RFC 3986 and the WHATWG URL standards.
Before PHP 8.5
$components = parse_url("https://php.net/releases/8.5/en.php");
var_dump($components['host']);
// string(7) "php.net"
PHP 8.5+
use Uri\Rfc3986\Uri;
$uri = new Uri("https://php.net/releases/8.5/en.php");
var_dump($uri->getHost());
// string(7) "php.net"
New array_first() and array_last() functions
Simplified array element retrieval with new built-in functions for common operations.
Before PHP 8.5
$php = [
'php-82' => ['state' => 'security', 'branch' => 'PHP-8.2'],
'php-83' => ['state' => 'active', 'branch' => 'PHP-8.3'],
'php-84' => ['state' => 'active', 'branch' => 'PHP-8.4'],
'php-85' => ['state' => 'upcoming', 'branch' => 'PHP-8.5'],
];
$upcomingRelease = null;
foreach ($php as $key => $version) {
if ($version['state'] === 'upcoming') {
$upcomingRelease = $version;
break;
}
}
var_dump($upcomingRelease);
PHP 8.5+
$php = [
'php-82' => ['state' => 'security', 'branch' => 'PHP-8.2'],
'php-83' => ['state' => 'active', 'branch' => 'PHP-8.3'],
'php-84' => ['state' => 'active', 'branch' => 'PHP-8.4'],
'php-85' => ['state' => 'upcoming', 'branch' => 'PHP-8.5'],
];
$upcomingRelease = array_first(
array_filter(
$php,
static fn($version) => $version['state'] === 'upcoming'
));
var_dump($upcomingRelease);
Closures and First Class Callables in Constant Expressions
PHP 8.5 allows using closures and first-class callables in constant expressions, enabling more powerful and flexible constant definitions.
Before PHP 8.5
final class CalculatorTest extends \PHPUnit\Framework\TestCase
{
#[DataProvider('subtractionProvider')]
public function testSubtraction(
int $minuend,
int $subtrahend,
int $result
): void
{
$this->assertSame(
$result,
Calculator::subtract($minuend, $subtrahend)
);
}
public static function subtractionProvider(): iterable
{
for ($i = -10; $i <= 10; $i++) {
yield [$i, $i, 0];
yield [$i, 0, $i];
yield [0, $i, -$i];
}
}
}
PHP 8.5+
final class CalculatorTest
{
#[Test\CaseGenerator(static function (): iterable
{
for ($i = -10; $i <= 10; $i++) {
yield [$i, $i, 0];
yield [$i, 0, $i];
yield [0, $i, -$i];
}
})]
public function testSubtraction(
int $minuend,
int $subtrahend,
int $result
)
{
\assert(
Calculator::subtract($minuend, $subtrahend) === $result
);
}
}
Persistent cURL Share Handles
New CurlSharePersistentHandle class, curl_multi_get_handles(), curl_share_init_persistent() functions are available.
Before PHP 8.5
final readonly class PhpVersion {
public function __construct(
public readonly string $version
) {}
}
$php = new PhpVersion('8.5');
var_dump($php);
PHP 8.5+
final readonly class PhpVersion {
public function __construct(
public readonly string $version
) {}
}
$php = new PhpVersion('8.5');
var_dump($php);
New Classes, Interfaces, and Functions
PHP 8.5 introduces several new classes, interfaces, and functions that expand the language's capabilities.
Property Promotion
Now available for final classes
Attributes for Constants
Attributes are now available for constants
#[\Override] for Properties
The Override attribute now works on properties
#[\Deprecated] for Traits
Deprecation attribute now available for traits
Asymmetric Visibility
Now available for static properties
#[\DelayedTargetValidation]
New attribute for delayed validation
Error Handler Functions
New get_error_handler() and get_exception_handler()
Closure::getCurrent
New method to get current closure
DOM Methods
New getElementsByClassName() and insertAdjacentHTML()
Enchant Functions
New dictionary management functions
grapheme_levenshtein()
New function for grapheme distance calculation
OPcache Function
New opcache_is_script_cached_in_file_cache()
Reflection Methods
New ReflectionConstant::getFileName(), getExtension(), getExtensionName(), getAttributes(), and ReflectionProperty::getMangledName()
Deprecations & Changes
PHP 8.5 continues to refine the language by deprecating older functionalities.
Roadmap
Looking ahead at the future of PHP development and release cycles.
PHP 8.3
Nov 2023
PHP 8.4
Nov 2024
PHP 8.5
Nov 2025
PHP 9.0
Future
Each release branch is actively supported for two years from its initial stable release. After this period, each branch is supported for an additional year for critical security issues only.