PHP 8.5 is here!
PHP 8.5 shipped a few days ago, and with it a handful of small new features!
Focus on 2 of the ones I was looking forward to the most.
1. The pipe operator |>: my personal favourite
PHP 8.5 introduces the pipe (|>) operator, which lets you chain callables, read top to bottom.
Before PHP 8.5
$slug = urlencode(
trim(
strtolower($title)
)
);
$slug = urlencode(
preg_replace('/\s+/', '-',
trim(
strtolower($title)
)
)
);
With PHP 8.5
$slug = $title
|> strtolower(...) // lowercase
|> trim(...) // strip leading/trailing spaces
|> urlencode(...); // final URL encoding
That's honestly a lot more readable!
There are still a few limits:
- callables must have only one required parameter
- callables must return a value
- each pipe's return value is the next pipe's input
This, for example, will not work:
$slug = $title
|> strtolower(...)
|> trim(...)
|> preg_replace('/\s+/', '-', ...) // won't work: more than one required parameter
|> urlencode(...);
Don't panic though! Pipe accepts any kind of callable, remember?
$slug = $title
|> strtolower(...)
|> trim(...)
|> (fn(string $subject): string => preg_replace('/\s+/', '-', $subject)) // this works: one parameter, one return value
|> urlencode(...);
So you can do some pretty nice things. Imagine: you fetch a list of images, you want those with a specific tag, and you want to count them.
It would look something like this (for the example, assume we always get all images back):
$count = count(
array_filter(
$imageRepository->find(),
fn(Image $img): bool => $img->hasTag('tag')
)
);
With pipe:
$count = $imageRepository->find()
|> (fn(array $images) => array_filter($images, fn(Image $img): bool => $img->hasTag('tag')))
|> count(...);
Object / data-processing example
One last example for the road:
$user
|> loadProfile(...) // load the user's full profile
|> enrichProfile(...) // add computed data or whatever you need
|> json_encode(...); // turn it all into JSON
We can finally stop nesting things into unreadable spaghetti!
2. array_first() and array_last()
These two — I never really understood why we didn't get them earlier. Until now, you had to go through reset() and end() to grab the first or last element, but that meant mutating the internal pointer.
You could also play with array_key_first() and array_key_last(), but it was fairly verbose.
$last = $array[array_key_last($array)]; // didn't touch the pointer
$last = end($array); // did touch the pointer
$first = $array[array_key_first($array)]; // didn't touch the pointer
$first = reset($array); // did touch the pointer
Now we finally have the simple counterpart to array_key_first() and array_key_last():
$latest = array_last($notifications); // the last element
$oldest = array_first($notifications); // the first
One thing to know: it returns the element's value.
$array = ['foo' => 1, 'bar' => 2];
array_last($array); // returns 2
array_first($array); // returns 1
3. Other additions
Other additions land with PHP 8.5, less spectacular:
- Two new getters show up to help with debugging:
get_exception_handler()andget_error_handler(). Nothing special to add; if you want more, see the PHP Watch docs . locale_is_right_to_left(): detect "right-to-left" locales. Handy for internationalisation. Read morecurl_multi_get_handles(): get the handles from a multi-handle. Read more- New constant
PHP_BUILD_DATE: get the compilation date. Read more - New CLI option
php --ini=diff: show only non-default INI directives. Read more
