PHP 8.5: What's Coming Next

By Amas
PHP 8.5: What's Coming Next

As PHP developers, we've witnessed an incredible transformation over the past few years. From PHP 7's performance revolution to PHP 8's union types and attributes, each release has brought features that genuinely make our daily coding lives better. PHP 8.5 continues this trend, but with a different focus – it's less about groundbreaking paradigm shifts and more about those "finally!" moments we all experience.

You know those times when you're writing code and think, "There has to be a cleaner way to do this"? Or when you hit a fatal error and spend way too long figuring out which function in your call stack actually caused it? PHP 8.5 addresses many of these everyday frustrations with thoughtful additions that feel like they should have been there all along.

This release is particularly exciting because it shows the PHP team listening closely to the community. The pipe operator, for instance, has been a long-requested feature inspired by functional programming languages. Meanwhile, fatal error stack traces solve a debugging pain point that's frustrated developers for years.

Here's what's coming in PHP 8.5 – features that might not make headlines but will definitely make your code cleaner and your debugging sessions shorter.

The Pipe Operator: Cleaner Function Chaining

Perhaps the most visually striking addition is the new pipe operator (|>), which allows you to chain function calls in a more readable left-to-right manner. If you've ever worked with languages like F# or Elixir, this will feel familiar, and if you haven't, you're in for a treat.

Instead of deeply nested function calls or multiple intermediate variables, you can now write:

$message = "Welcome Back"
    |> strtolower(...)
    |> trim(...)
    |> ucfirst(...);

// Result: "Welcome back"

This is much more readable than the traditional nested approach:

$message = ucfirst(trim(strtolower("Welcome Back")));

The pipe operator works with any callable - functions, methods, closures, and even classes with __invoke.

However, the pipe operator does have some important limitations to keep in mind:

  • Each function in the chain must accept only one required parameter (the piped value becomes the first argument)
  • Functions with by-reference parameters aren't supported (since there's no actual variable to reference)

 

Better Error Debugging with Stack Traces

PHP 8.5 finally adds stack traces to fatal errors, making debugging much easier. Previously, when your script hit a fatal error like running out of memory, you'd only see the error message and line number. Now you get the full call stack:

Fatal error: Allowed memory size exhausted in script.php on line 8
Stack trace:
#0 script.php(12): process_large_data()
#1 script.php(20): handle_request()
#2 {main}

This feature is controlled by the new fatal_error_backtraces INI directive and is enabled by default.

New Array Convenience Functions

Two simple but useful functions join PHP's array toolkit, filling a gap that many developers have worked around for years. While PHP 7.3 gave us array_key_first() and array_key_last() to get the keys, getting the actual values required additional steps.

$fruits = ['apple', 'banana', 'cherry'];
$first = array_first($fruits);  // 'apple'
$last = array_last($fruits);    // 'cherry'

// Works with associative arrays too
$scores = ['alice' => 95, 'bob' => 87, 'charlie' => 92];
$first_score = array_first($scores);  // 95
$last_score = array_last($scores);    // 92

Before PHP 8.5, getting the first value from an array often meant writing reset($array) or array_values($array)[0], both of which feel clunky and aren't immediately obvious to other developers reading your code. The new functions make intent crystal clear.

One important note: both functions return null for empty arrays, but since null can also be a valid array value, you might need additional checks in some cases:

$data = [null, 'second', 'third'];
$first = array_first($data);  // null (valid value)

$empty = [];
$first = array_first($empty); // null (empty array)

// If you need to distinguish between these cases
if (empty($data)) {
    // Array is actually empty
} elseif (array_first($data) === null) {
    // First value is null
}

These complement the existing array_key_first() and array_key_last() functions from PHP 7.3, giving you complete access to both ends of your arrays without any mental gymnastics.

Handler Introspection Functions

PHP 8.5 introduces get_error_handler() and get_exception_handler() functions to retrieve currently set error and exception handlers. This fills a gap where you could set and restore handlers but couldn't easily check what was currently active:

set_error_handler('my_error_handler');
$current_handler = get_error_handler(); // Returns 'my_error_handler'

if (get_exception_handler() === null) {
    // No exception handler is currently set
    set_exception_handler('my_exception_handler');
}

 

Internationalization Features

The Intl extension gets several improvements. A new locale_is_right_to_left() function (and corresponding Locale::isRightToLeft() method) helps determine if a locale uses right-to-left scripts:

locale_is_right_to_left('en-US');  // false
locale_is_right_to_left('ar-SA');  // true
locale_is_right_to_left('he-IL');  // true

There's also a new IntlListFormatter class for creating locale-aware lists:

$formatter = new IntlListFormatter('en-US');
echo $formatter->format(['Paris', 'London', 'Tokyo']);
// "Paris, London, and Tokyo"

$formatter = new IntlListFormatter('de-DE');
echo $formatter->format(['Paris', 'London', 'Tokyo']);
// "Paris, London und Tokyo"

 

cURL Enhancement

For those working with cURL multi-handles, the new curl_multi_get_handles() function returns all handles associated with a multi-handle, eliminating the need to manually track them:

 

$multi = curl_multi_init();
$handle1 = curl_init('https://api.example.com/users');
$handle2 = curl_init('https://api.example.com/posts');

curl_multi_add_handle($multi, $handle1);
curl_multi_add_handle($multi, $handle2);

$all_handles = curl_multi_get_handles($multi);
// Returns [$handle1, $handle2]

 

Looking Forward

PHP 8.5 continues the language's evolution toward more expressive and developer-friendly syntax while maintaining backward compatibility. The pipe operator, in particular, represents a significant step toward functional programming patterns that many developers have been requesting.

These features collectively make PHP code more readable, debugging more informative, and international development more accessible. While none are groundbreaking individually, together they represent meaningful quality-of-life improvements for PHP developers worldwide.

I personally can't wait to get my hands on PHP 8.5 once it's release to try these features!

Until then, keep building great software! 🚀

Share this post.
Liked that? Subscribe to our newsletter for more
Ship fast & don't reinvent the wheel

Build your SaaS using SaaSykit

SaaSykit is a SaaS boilerplate that comes packed with all components required to run a modern SaaS software.

Don't miss this

You might also like