By continuing your visit to this site, you accept the use of cookies. Read more

Scout APM helps PHP developers pinpoint N+1 queries, memory leaks & more so you can troubleshoot fast & get back to coding faster. Start your free 14-day trial today .

« back — written by Brent on November 26, 2019

# What's new in PHP 7.4

PHP 7.4 is the latest stable version of PHP. It was released on November 28, 2019 and it's the last version before PHP 8. It brings lots of new features, syntax additions and fixes. In this post you'll find a list with everything that's new and changed to help you prepare for the upgrade. Let's start though with a few highlights, included in PHP 7.4:

# New features

PHP 7.4 comes with a remarkable amount of new features. We'll start with a list of all new features, and then look at changes and deprecations.

A note before we dive in though: if you're still on a lower version of PHP, you'll also want to read what's new in PHP 7.3.

# Arrow functions rfc

Arrow functions, also called "short closures", allow for less verbose one-liner functions.

While you'd previously write this:

array_map ( function ( User $user) { return $user->id; }, $users)

You can now write this:

array_map ( fn ( User $user) => $user->id, $users)

There are a few notes about arrow functions:

They can always access the parent scope, there's no need for the use keyword.

keyword. $this is available just like normal closures.

is available just like normal closures. Arrow functions may only contain one expression, which is also the return statement.

You can read about them in depth here.

# Typed properties rfc

Class variables can be type hinted:

class A { public string $name; public ?Foo $foo; }

There's lots to tell about this feature, so I wrote a dedicated post about them.

# Improved type variance rfc

I also wrote about PHP's type system in the past, so it's good to see some improvements are actually arriving in PHP's core.

Type variance is another topic worth its own blog post, but in short: you'll be able use covariant return types –

class ParentType {} class ChildType extends ParentType {} class A { public function covariantReturnTypes () : ParentType { } } class B extends A { public function covariantReturnTypes () : ChildType { } }

– and contravariant arguments.

class A { public function contraVariantArguments ( ChildType $type) { } } class B extends A { public function contraVariantArguments ( ParentType $type) { } }

# Null coalescing assignment operator rfc

Next is the null coalescing assignment operator, a shorthand for null coalescing operations. Instead of doing this:

$data[ 'date' ] = $data[ 'date' ] ?? new DateTime ();

You can do this:

$data[ 'date' ] ??= new DateTime ();

You can read more about this operator in my post about PHP shorthands.

# Array spread operator rfc

Next up, it's now possible to use the spread operator in arrays:

$arrayA = [ 1 , 2 , 3 ]; $arrayB = [ 4 , 5 ]; $result = [ 0 , ...$arrayA, ...$arrayB, 6 , 7 ];

Note that this only works with arrays with numerical keys.

# Numeric Literal Separator rfc

PHP 7.4 allows for underscores to be used to visually separate numeric values. It looks like this:

$unformattedNumber = 107925284.88 ; $formattedNumber = 107 _925_284 .88 ;

The underscores are simply ignored by the engine.

# Foreign function interface rfc

Moving on to some more core-level features: foreign function interface or "FFI" in short, allows us to call C code from userland. This means that PHP extensions could be written in pure PHP and loaded via composer.

It should be noted though that this is a complex topic. You still need C knowledge to be able to properly use this feature.

Another lower-level feature is preloading. It's is an amazing addition to PHP's core, which can result in some significant performance improvements.

In short: if you're using a framework, its files have to be loaded and linked on every request. Preloading allows the server to load PHP files in memory on startup, and have them permanently available to all subsequent requests.

The performance gain comes of course with a cost: if the source of preloaded files are changed, the server has to be restarted.

Do you want to know more? I wrote a dedicated post about setting up and using preloading and have also done some preloading benchmarks.

# Custom object serialization rfc

Two new magic methods have been added: __serialize and __unserialize . The difference between these methods and __sleep and __wakeup is discussed in the RFC.

# Reflection for references rfc

Libraries like Symfony's var dumper rely heavily on the reflection API to reliably dump a variable. Previously it wasn't possible to properly reflect references, resulting in these libraries relying on hacks to detect them.

PHP 7.4 adds the ReflectionReference class which solves this issue.

# Weak references rfc

Weak references are references to objects, which don't prevent them from being destroyed.

This function provides the same functionality as str_split , but on multi-byte strings.

# Password Hashing Registry rfc

Internal changes have been made to how hashing libraries are used, so that it's easier for userland to use them.

More specifically, a new function password_algos has been added which returns a list of all registered password algorithms.

The RFC was a little unclear about the benefits, luckily Sara was able to provide some more context:

It means that ext/sodium (or anyone really) can register password hashing algorithms dynamically. The upshot of which is that argon2i and argon2id will be more commonly available moving forward

# Changes and deprecations

Besides new features, there are also lots of changes to the language. Most of these changes are non-breaking, though some might have an effect on your code bases.

Note that deprecation warnings aren't per definition "breaking", but merely a notice to the developer that functionality will be removed or changed in the future. It would be good not to ignore deprecation warnings, and to fix them right away; as it will make the upgrade path for PHP 8.0 more easy.

# Left-associative ternary operator deprecation rfc

The ternary operator has some weird quirks in PHP. This RFC adds a deprecation warning for nested ternary statements. In PHP 8, this deprecation will be converted to a compile time error.

1 ? 2 : 3 ? 4 : 5 ; ( 1 ? 2 : 3 ) ? 4 : 5 ;

# Exceptions allowed in __toString rfc

Previously, exceptions could not be thrown in __toString . They were prohibited because of a workaround for some old core error handling mechanisms, but Nikita pointed out that this "solution" didn't actually solve the problem it tried to address.

This behaviour is now changed, and exceptions can be thrown from __toString .

# Concatenation precedence rfc

If you'd write something like this:

echo "sum: " . $a + $b;

PHP would previously interpret it like this:

echo ( "sum: " . $a) + $b;

PHP 8 will make it so that it's interpreted like this:

echo "sum: " . ($a + $b);

PHP 7.4 adds a deprecation warning when encountering an unparenthesized expression containing a . before a + or - sign.

# array_merge without arguments upgrading

Since the addition of the spread operator, there might be cases where you'd want to use array_merge like so:

$merged = array_merge (...$arrayOfArrays);

To support the edge case where $arrayOfArrays would be empty, both array_merge and array_merge_recursive now allow an empty parameter list. An empty array will be returned if no input was passed.

# Curly brackets for array and string access rfc

It was possible to access arrays and string offsets using curly brackets:

$array{ 1 }; $string{ 3 };

This has been deprecated.

# Invalid array access notices rfc

If you were to use the array access syntax on, say, an integer; PHP would previously return null . As of PHP 7.4, a notice will be emitted.

$i = 1 ; $i[ 0 ];

Changes were made to proc_open so that it can execute programs without going through a shell. This is done by passing an array instead of a string for the command.

You used to only be able to strip multiple tags like so:

strip_tags ($string, '<a><p>' )

PHP 7.4 also allows the use of an array:

strip_tags ($string, [ 'a' , 'p' ])

# ext-hash always enabled rfc

This extension is now permanently available in all PHP installations.

# PEAR not enabled by default externals

Because PEAR isn't actively maintained anymore, the core team decided to remove its default installation with PHP 7.4.

# Several small deprecations rfc

This RFC bundles lots of small deprecations, each with their own vote. Be sure to read a more detailed explanation on the RFC page, though here's a list of deprecated things:

The real type

type Magic quotes legacy

array_key_exists() with objects

with objects FILTER_SANITIZE_MAGIC_QUOTES filter

filter Reflection export() methods

methods mb_strrpos() with encoding as 3rd argument

with encoding as 3rd argument implode() parameter order mix

parameter order mix Unbinding $this from non-static closures

from non-static closures hebrevc() function

function convert_cyr_string() function

function money_format() function

function ezmlm_hash() function

function restore_include_path() function

function allow_url_include ini directive

# Other changes upgrading

You should always take a look at the full UPGRADING document when upgrading PHP versions.

Here are some changes highlighted:

Calling parent:: in a class without a parent is deprecated.

in a class without a parent is deprecated. Calling var_dump on a DateTime or DateTimeImmutable instance will no longer leave behind accessible properties on the object.

on a or instance will no longer leave behind accessible properties on the object. openssl_random_pseudo_bytes will throw an exception in error situations.

will throw an exception in error situations. Attempting to serialise a PDO or PDOStatement instance will generate an Exception instead of a PDOException .

or instance will generate an instead of a . Calling get_object_vars() on an ArrayObject instance will return the properties of the ArrayObject itself, and not the values of the wrapped array or object. Note that (array) casts are not affected.

on an instance will return the properties of the itself, and not the values of the wrapped array or object. Note that casts are not affected. ext/wwdx has been deprecated.

# RFC voting process improvements

This is technically not an update related to PHP 7.4, though it's worth mentioning: the voting rules for RFC's have been changed.

They always need a 2/3 majority in order to pass.

There are not more short voting periods, all RFCs must be open for at least 2 weeks.

# Hang on now…

If you've made it this far, chances are you are interested in PHP. Maybe you're also interested in reading my other content? Here are some of the things I wrote.

Oh and lastly, follow me on Twitter if you want to stay up to date!