What's new in PHP 8.4
It's that time again, a new version of PHP. Version 8.4 already.
This version is packed with changes and new features, changes and deprecations.
Here is a summary of the features I can't wait to play around with.
The release date for PHP 8.4 is officially 2024-11-21. So that's next week.
Let's start of with deprecations, there is only one that I want to highlight.
Implicitly nullable parameter declarations
We had this strange thing around that made a variable nullable. I was never a fan of using this though.
function performAction(array $data = null) {}
// Implicitly marking parameter $data as nullable is deprecated, the explicit nullable type must be used instead
If we now want to make the variable $data
explicitly nullable we can now add a ?
before it.
function performAction(?array $data = null) {}
New Array functions
There are 4 new array functions available for us, which we can use to search and inspect array elements ith a callback function: array_find
, array_find_key
, array_all
, and array_any
.
array_find
This function will return the value
of the first element for which the callback returns true
.
function is_even(int $value): bool {
return $value % 2 === 0;
}
array_find([1, 2, 3, 4, 5], 'is_even');
// 2
array_find_key
This function will return the key
of the first element for which the callback returns true
.
function is_even(int $value): bool {
return $value % 2 === 0;
}
array_find_key(['foo' => 1, 'bar' => 2, 'baz' => 3], 'is_even');
// "bar"
array_all
This function will return true
if the callback returns true
for all elements of the array.
array_all(
['foo@example.com', 'bar@example.com', 'baz@example.com'],
fn($value) => filter_var($value, FILTER_VALIDATE_EMAIL),
);
// true
array_all(
['foo@example.com', 'bar@example.com', 'baz'],
fn($value) => filter_var($value, FILTER_VALIDATE_EMAIL),
);
// false
array_any
This function will return true
if the callback returns true
for any element of the array.
array_any(
['foo@example.com', 'https://php.watch', 'foobar'],
fn($value) => filter_var($value, FILTER_VALIDATE_URL),
);
// true
New mb_ucfirst and mb_lcfirst functions
PHP had ucfirst
and lcfirst
for ages. Until now mbstring
didn't support a multi-byte safe version or alternative for the ucfirst
and lcfirst
functions.
But now the wait is over, now we can use mb_ucfirst
and mb_lcfirst
. In addition, like the other mb_
functions it also accepts an optional encoding parameter.
mb_ucfirst('Bert'); // Best
mb_ucfirst('BERT'); // BERT
mb_ucfirst('bErt'); // BErt
mb_ucfirst('bert'); // BErt
mb_lcfirst('Bert'); // bert
mb_lcfirst('BERT'); // bERT
mb_lcfirst('bErt'); // bErt
mb_lcfirst('bert'); // bert
New rounding modes
The round()
function will round a given float to the nearest integer or decimal (based on a precision). with PHP 8.4 we'll be able to use 4 new rounding methods.
PHP_ROUND_CEILING
This method will round to the nearest integer bigger than the number.
For example 1.1 and 1.5 to 2 and -1.1 and -1.5 to -1
PHP_ROUND_FLOOR
This method will round to the nearest integer lower than the number.
For example 1.1 and 1.9 to 1 and -1.1 and -1.9 to -2
PHP_ROUND_TOWARD_ZERO
This method will round to the nearest integer in the direction of 0.
For example 1.1 and 1.9 to 1 and -1.1 and -1.9 to -1
PHP_ROUND_AWAY_FROM_ZERO
This method will round to the nearest integer in the direction away from 0.
For example 1.1 and 1.9 to 2 and -1.1 and -1.9 to -2
New without parentheses
We'll be able to create new object and call methods directly on them without wrapping them into parentheses.
// Prior to PHP 8.4
$result = (new SomeNewClass($param))->getSomething();
// In PHP 8.4
$result = new SomeNewClass($param)->getSomething();
Default Bcrypt cost changed from 10 to 12
The default cost used in the built-in password hashing changed from 10 to 12 for both PASSWORD_BCRYPT
and PASSWORD_DEFAULT
.
If needed we can still encrypt with a lower cost.
password_hash('verySafePassword', PASSWORD_BCRYPT, ['cost' => 10]);
Lazy Objects
We'll now have native support for lazy objects, a common pattern used by frameworks to build proxy objects.
$initializer = static function (MyClass $proxy): MyClass {
return new MyClass(123);
};
$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyProxy($initializer);
In closing
A bunch of new features, changes and deprecations. Which I think will make our work easier / faster in the long run.
Happy coding!
#php