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

# Short closures rfc

Short closures allow for less verbose one-liner functions.

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

A few notes about short closures:

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 say about this feature, so I wrote a dedicated post about them.

# Improved type variance rfc

I 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 a topic worth its own blog post; 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

Instead of doing this:

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

You can do this:

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

# Array spread operator RFC

It's now possible to use the spread operator in arrays:

$arrayA = [1, 2, 3];

$arrayB = [4, 5];

$result = [0, ...$arrayA, ...$arrayB, 6 ,7];

// [0, 1, 2, 3, 4, 5, 6, 7]

Note that this only works with arrays with numerical keys.

# Foreign function interface rfc

Foreign Function Interface, FFI in short, allows calling C code from userland. This means that PHP extensions can be written in pure PHP.

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

# Preloading rfc

Preloading is an amazing addition to PHP's core, which can result in some major performance improvements.

In short: if you're using a framework today, its files have to be loaded and recompiled 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.

# Custom object serialization rfc

This RFC adds two new magic methods: __serialize and __unserialize. The difference between these methods and __sleep and __wakeup is discussed in the RFC.

# 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.

# 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 an '.' before a '+' or '-'.

# Allow exceptions 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.

# 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.

# Reflection for references rfc

Libraries like Symfony's var dumper rely heavily on the reflection API to reliably dump a variable. Previously, no proper reflection support for references was available, causing these libraries to rely on hacks to detect references.

PHP 7.4 adds the ReflectionReference class which solves this issue.

# mb_str_split added RFC

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

# ext-hash always enabled rfc

As the title says, 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.

# Password Hashing Registry RFC

Internal changes to how hashing libraries are used, so that it's easier for userland to use them. More specifically, a new function password_algos is added which returns a list of all registered password algorithms.

# Deprecate ext/wwdx RFC

This data exchange format was never standardised, and now its extension is deprecated.

# Short PHP tags deprecated RFC

The short open tag <? has been deprecated and will be removed in PHP 8. The short echo tag <?= is unaffected.

# Left-associative ternary operator deprecation RFC

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

1 ? 2 : 3 ? 4 : 5;   // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok

# Backward incompatible changes UPGRADING

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

Here are some of the backward incompatible changes highlighted:

# 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!