Modern APIs. Enhanced debugging. Refined syntax. The evolution of PHP continues with thoughtful improvements.
PHP 8.5 introduces powerful new capabilities with comprehensive code examples showing before and after comparisons.
New URI extension providing standards-compliant URL parsing with modern object-oriented API
$components = parse_url("https://php.net/releases/8.5/en.php");
var_dump($components['host']);
// string(7) "php.net"
use Uri\Rfc3986\Uri;
$uri = new Uri("https://php.net/releases/8.5/en.php");
var_dump($uri->getHost());
// string(7) "php.net"
Modify properties while cloning, perfect for readonly properties and immutable objects
final readonly class PhpVersion {
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version) {
$newObject = clone $this;
$newObject->version = $version;
return $newObject;
}
}
var_dump(new PhpVersion()->withVersion('PHP 8.5'));
// Fatal error: Uncaught Error:
// Cannot modify readonly property PhpVersion::$version
final readonly class PhpVersion {
public function __construct(
public string $version = 'PHP 8.4',
) {}
public function withVersion(string $version) {
return clone($this, ['version' => $version]);
}
}
$version = new PhpVersion();
var_dump(
$version->withVersion('PHP 8.5'),
$version->version,
);
Chain function calls naturally with the new pipe operator for cleaner, more readable code
$input = ' Some kind of string. ';
$output = strtolower(
str_replace(['.', '/', '…'], '',
str_replace(' ', '-',
trim($input)
)
)
);
$input = ' Some kind of string. ';
$output = $input
|> trim(...)
|> (fn (string $string) => str_replace(' ', '-', $string))
|> (fn (string $string) => str_replace(['.', '/', '…'], '', $string))
|> strtolower(...);
Mark functions whose return values should not be ignored, improving code safety
function getPhpVersion(): string {
return 'PHP 8.4';
}
getPhpVersion(); // No Errors
#[\NoDiscard]
function getPhpVersion(): string {
return 'PHP 8.4';
}
getPhpVersion();
// Warning: The return value of function
// getPhpVersion() should either be used or
// intentionally ignored by casting it as (void)
Use closures and first-class callables directly in attributes and constant expressions
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];
}
}
}
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 * -1)];
}
})]
public function testSubtraction(
int $minuend,
int $subtrahend,
int $result
)
{
\assert(
Calculator::subtract($minuend, $subtrahend) === $result
);
}
}
Simplified API for persistent cURL share handles with automatic management
$sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
$ch1 = curl_init('https://php.net/');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_exec($ch1);
$ch2 = curl_init('https://thephp.foundation/');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_exec($ch2);
curl_share_close($sh);
curl_close($ch1);
curl_close($ch2);
$sh = curl_share_init_persistent([
CURL_LOCK_DATA_DNS,
CURL_LOCK_DATA_CONNECT
]);
$ch1 = curl_init('https://php.net/');
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_exec($ch1);
$ch2 = curl_init('https://thephp.foundation/');
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_exec($ch2);
curl_close($ch1);
curl_close($ch2);
Convenient functions to retrieve the first and last elements of arrays
$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 = [
'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);
PHP 8.5 includes many other enhancements for better developer experience.
Property promotion is now available for final class constructors, making immutable data classes easier to create.
Constants now support attributes, allowing better metadata and documentation directly in code.
The #[\Override] attribute now works on properties, providing validation when overriding parent properties.
Mark traits as deprecated with the #[\Deprecated] attribute to help identify legacy code.
Static properties now support asymmetric visibility modifiers for fine-grained access control.
New attribute for improved control over attribute validation timing and behavior.
New get_error_handler(), get_exception_handler() and Closure::getCurrent for inspecting handlers.
Dom\Element::getElementsByClassName() and insertAdjacentHTML() for better DOM manipulation.
New enchant_dict_remove_from_session() and enchant_dict_remove() spell-checking functions.
Calculate edit distance between strings using grapheme clusters with this new function.
opcache_is_script_cached_in_file_cache() checks if a script is in the file-based OPcache.
New methods: ReflectionConstant::getFileName(), getExtension(), getAttributes(), and more.
New CurlSharePersistentHandle class and curl_multi_get_handles() function.
PHP 8.5 focuses on new features with minimal breaking changes. Review your application for any deprecated features from previous versions that may be removed in future releases.
Smoothly transition your applications to PHP 8.5 with these guidelines.
Adopt the pipe operator for function chaining, use array_first() and array_last(), and leverage the new URI extension.
Run your test suite in a staging environment, enable error reporting, and update dependencies to PHP 8.5-compatible versions.
Consult the official migration guide and review RFCs for detailed information on all changes and new features.
Download PHP 8.5 for your platform and start using modern PHP features today.