What’s New in PHP 8.5? 10 Game‑Changing Features You Must Try
PHP 8.5 introduces a suite of powerful enhancements—including the pipeline operator, native array_first/array_last functions, a new URI extension, closure recursion support, constant expression closures, fatal error backtraces, INI diff mode, #[NoDiscard] attribute, clone overrides, and a build‑date constant—plus four key deprecations.
Pipeline Operator (|>)
The long‑awaited pipeline operator lets you chain callable objects left‑to‑right, passing the result of each call to the next. Previously you needed nested calls or temporary variables:
// Method 1: nested calls (hard to read)
$result = trim(str_shuffle(strtoupper("Hello World")));
// Method 2: temporary variables (verbose)
$result = "Hello World";
$result = strtoupper($result);
$result = str_shuffle($result);
$result = trim($result);With the pipeline operator the same logic becomes concise:
$result = "Hello World"
|> strtoupper(...)
|> str_shuffle(...)
|> trim(...);
// Output: "LWHO…"Native array_first() and array_last()
PHP 8.5 adds two functions to fetch the first or last element of an array, complementing array_key_first() and array_key_last(). They work with non‑integer keys and do not alter the internal iterator.
array_first(["single element"]); // "single element"
array_last(["single element"]); // "single element"
array_first([]); // NULL
array_last([]); // NULL
array_first([1 => 'a', 0 => 'b', 3 => 'c', 2 => 'd']); // 'a'
array_last([1 => 'a', 0 => 'b', 3 => 'c', 2 => 'd']); // 'd'New URI Extension
A standards‑compliant URI parser based on RFC 3986 and WHATWG URL is now part of the core library.
use Uri\Rfc3986\Uri;
$url = new Uri('HTTPS://thephp.foundation:443/sp%6Fnsor/');
$defaultPortForScheme = match ($url->getScheme()) {
'http' => 80,
'https' => 443,
'ssh' => 22,
default => null,
};
// Remove default port from the URL.
if ($url->getPort() === $defaultPortForScheme) {
$url = $url->withPort(null);
}
echo $url->toString(), PHP_EOL; // https://thephp.foundation/sponsor/Closure Recursion via Closure::getCurrent()
PHP 8.5 enables recursive closures without naming the function explicitly. Example – Fibonacci sequence:
$fibonacci = function (int $n) {
if (0 === $n || 1 === $n) {
return $n;
}
$fn = Closure::getCurrent();
return $fn($n - 1) + $fn($n - 2);
};
echo $fibonacci(10) . "
"; // 55Closures in Constant Expressions
Closures can now appear in constant expressions, allowing them as default property values or other compile‑time contexts.
function my_array_filter(
array $array,
Closure $callback = static function ($item) { return !empty($item); },
) {
$result = [];
foreach ($array as $item) {
if ($callback($item)) {
$result[] = $item;
}
}
return $result;
}
my_array_filter([0, 1, 2, '', 'foo', 'bar']); // [1, 2, "foo", "bar"]Fatal Error Backtraces ( fatal_error_backtraces )
A new ini setting controls whether backtraces are shown for fatal errors (default = 1). Example output:
Fatal error: Cannot redeclare class B (previously declared in /srv/app/index.php:11) in /srv/app/b.php on line 3
Stack trace:
#0 /srv/app/index.php(6): require()
#1 /srv/app/index.php(21): A->loadClassB()
#2 {main}INI Diff Option ( --ini=diff )
The CLI flag shows only INI settings that differ from the default configuration.
$ php --ini=diff
Non-default INI settings:
allow_url_include: "0" -> ""
auto_append_file: (none) -> ""
...#[\NoDiscard] Attribute
When applied to a function, the attribute triggers a warning if the return value is ignored, helping catch accidental discarding of expensive results.
Clone with Property Overwrite
The clone() operation now accepts a second argument – an associative array of properties that override the cloned object's state, useful for creating modified copies of immutable value objects.
PHP_BUILD_DATE Constant
A new constant returns the build date of the PHP binary. The OPcache extension is now statically compiled into the core, guaranteeing its availability.
Key Deprecations (4 items)
Backticks as shell_exec alias : The backtick operator (`) is deprecated; use shell_exec() instead.
__sleep() and __wakeup() magic methods : Deprecated in favor of __serialize() and __unserialize().
Non‑standard type cast names : Casts like (integer), (boolean), (double), (binary) are deprecated; use (int), (bool), (float), (string) instead.
Semicolon after case in switch : The legacy syntax with a trailing semicolon is deprecated; use a colon.
These changes aim to make PHP more modern, safer, and easier to maintain. Ready to upgrade to PHP 8.5?
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Tech Hub
Sharing cutting-edge internet technologies and practical AI resources.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
