What’s New in PHP 7.4 (Features, Deprecations, Updates)

About the PHP 7.4 release

PHP 7.4 was released on November 28, 2019 for General Availability. With this PHP release you can expect a noticeable performance increase. However, although PHP 7.4 improves performance and code readability, you can expect a true boost from PHP 8, as a JIT inclusion has already been approved for that version.By the way if you want to check how your current website is doing on performance here are the top metrics you can use.

But back to PHP 7.4!

Some of the key features of this new version are syntactic improvements, FFI (foreign function interface), engine changes, class preloading, and much more.

Here’s what we’ll cover in this article:

  1. Spread Operator in Array Expression
  2. Support for Arrow Functions
  3. Support for coalescing assign (??=) operator
  4. Support of typed properties
  5. Covariant Returns and Contravariant Parameters
  6. Support for WeakReferences
  7. Preloading
  8. Deprecations
  9. PHP 7.4 for WordPress users

Now let’s go over these features, deprecations, and updates one by one to understand what each of them does.

Features, Deprecations, Updates of PHP 7.4

Intricate coding shown on the black background

Let’s start with the first one:

Spread Operator in Array Expression

Since PHP 5.6, the argument unpacking syntax, a.k.a. Spread Operator, has been approved and used for unpacking Traversables and arrays into the argument list. To unpack the array or the Traversable you had to prepend it by 3 dots (…). Here is the example of how it is done in PHP:

function test(...$args) { var_dump($args); }   →   test(1, 2, 3);  

However, for PHP 7.4 the RFC offers a better solution by proposing to extend this feature with an array definition.

 
$arr = [...$args];

According to RFC, this new extension ensures better performance than the array_merge not only because it’s a language structure and array_merge a function, but also because it’s possible to perform compile-time optimization for constant arrays.

The Spread Operator supports any Traversable object The same can’t be said of array_merge which only supports arrays. Take a look at this example of an argument unpacking in an array expression:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

With the previous version, PHP 7.3, you’d get a Parse error, but with the new one, PHP 7.4, you’ll be returned an array:

 
array(5) {
	[0]=>
	string(6) "banana"
	[1]=>
	string(6) "orange"
	[2]=>
	string(5) "apple"
	[3]=>
	string(4) "pear"
	[4]=>
	string(10) "watermelon"
}

You can also unpack arrays returned by function directly into the new array:

 
function buildArray(){
	return ['red', 'green', 'blue'];
}
$arr1 = [...buildArray(), 'pink', 'violet', 'yellow'];

Finally, you can also use the generator syntax.

A normal function usually cannot be stopped before it has finished its task, that is to say before the last time it got executed. In contrast, generator syntax yields as many values as needed. You can stop the generator function in midway and then continue from where you left off.

function generator() {
	for ($i = 3; $i <= 5; $i++) {
		yield $i;
	}
}
$arr1 = [0, 1, 2, ...generator()];

Support for Arrow Functions

As mentioned by RFC, anonymous functions in PHP are usually quite verbose, even though most of the time they are performing a rather simple operation. This is due to a large amount of syntax and the need to manually import all used variables.

This makes the code hard to read and comprehend. That’s why RFC proposes a solution with shorter and simpler arrow functions also known as short closures.

These will eventually make the PHP code cleaner and more concise.
Let’s take a look at an example:

 

function cube($n){
	return ($n * $n * $n);
}
$a = [1, 2, 3, 4, 5];
$b = array_map('cube', $a);
print_r($b);

With PHP 7.4 you can write the function above with a better syntax. Here’s what it looks like:

 

$a = [1, 2, 3, 4, 5];
$b = array_map(fn($n) => $n * $n * $n, $a);
print_r($b);

Arrow functions also allow you to avoid the use keyword. Here’s how the use language construct is currently being used in anonymous functions:

 
$factor = 10;
$calc = function($num) use($factor){
	return $num * $factor;
};

Instead, with PHP 7.4, you can write the entire function above only with a single line. Here’s what that looks like:

$factor = 10;
$calc = fn($num) => $num * $factor;

In addition to that, arrow functions enable the use of the $this variable just like other regular closures. In short, with arrow functions the PHP coding becomes way more readable and maintainable. It also has some other features such as parameter and return types, variadic functions, default values, and much more.

Support for coalesce assign (??=) operator

Coalesce operator (??) was added with PHP 7 allowing web developers to simplify isset() check with a ternary operator. Before the release of PHP 7, our code looked something like this:

 
$data['username'] = (isset($data['username']) ? $data['username'] : 'guest');

With PHP 7, developers can write a much simpler code that looks something like this:

$data['username'] = $data['username'] ?? 'guest';

In order to make coding more intuitive for developers, RFC proposes the null coalescing assignment operator (??=). So, the code above is even more simplified like this:

$data['username'] ??= 'guest';

So if the left operand parameter is null, the value of the right-operand parameter will be used. The proposal of coalesce assignment was approved with 37 to 4 votes. However, keep in mind that if a coalesce operator functions as a comparison operator, with ??=, it’s used as an assignment operator.

Support of typed properties

A type declaration also known as type hint is a language construct used to specify the properties of the identifier. This feature has been available since PHP 5. Developers have been able to use it with object data type since PHP 7.2. So what is new for PHP 7.4?

PHP 7.4 brings type hinting to the next level by introducing a support for first-class property declarations.

So basically, a code that used to look like this:

 

class User {
    /** @var int $id */
    private $id;
    /** @var string $name */
    private $name;
 
    public function __construct(int $id, string $name) {
        $this-&gt;id = $id;
        $this-&gt;name = $name;
    }
 
    public function getId(): int {
        return $this-&gt;id;
    }
    public function setId(int $id): void {
        $this-&gt;id = $id;
    }
 
    public function getName(): string {
        return $this-&gt;name;
    }
    public function setName(string $name): void {
        $this-&gt;name = $name;
    }
}

Now can look like this:

class User {
    public int $id;
    public string $name;
 
    public function __construct(int $id, string $name) {
        $this-&gt;id = $id;
        $this-&gt;name = $name;
    }
    public function getId(): int {
        return $this-&gt;id;
    }
    public function setId(int $id): void {
        $this-&gt;id = $id;
    }
 
    public function getName(): string {
        return $this-&gt;name;
    }
    public function setName(string $name): void {
        $this-&gt;name = $name;
   }
}

This is done without sacrificing type safety.

This new feature supports all types except for void and callable. Here’s how RFC explains it:

  • The void type has very unclear semantics and in general is not useful.
  • The callable type’s behavior depends on the context. That’s why it’s not supported either.
 
public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;

You can safely use bool, int, float, string, array, object, iterable, self, parent, and any class of interface name along with nullable type.

They can be used on static properties:

public static iterable $staticProp;

And also on the var notations:

var bool $flag;

Type properties may have default values, but a default null value can have only the nullable properties.

public string $str = "foo";
public ?string $nullableStr = null;

Typed properties have been approved with 70 to 1 votes.

Covariant Returns and Contravariant Parameters

Variance refers to how subtyping between more complex types relates to subtyping between their components. For example, how should a list of Cats relate to a list of Animals? Or how should a function that returns Cat relate to a function that returns Animal?

  • Invariant: If the type of the super-type constrains the type of the subtype.
  • Covariant: If the ordering of types is preserved (types are ordered from more specific to more generic).
  • Contravariant: If it reverses the order (types are ordered from more generic to more specific).

Until PHP 7.4, PHP had mostly invariant parameter types and mostly invariant return types. This means that if a method of a super-type has a parameter or return type constraint of Animal then the corresponding parameter or return type constraint of the method of the sub-type must also be Animal. But now, with the 7.4 version, it’s possible to declare covariant returns and Contravariant Parameters on interface/class definitions.

Covariance allows a child method to return a more specific type than the return type of its parent method whereas contravariance allows a parameter type to be less specific in a child method, than that of its parent.

Here’s an example showing how covariance works by creating a simple abstract Animal parent class. Animal will be extended by children classes Cat and Dog.

name = $name;
    }

    abstract public function speak();
}

class Dog extends Animal
{
    public function speak()
    {
        echo $this-&gt;name . " barks";
    }
}

class Cat extends Animal 
{
    public function speak()
    {
        echo $this-&gt;name . " meows";
    }
}

However, they’re not methods that would return values in this example. That’s why we’ll add a few factories that’ll return a new object of class type Animal, Cat, or Dog.

 
adopt("Ricky");
$kitty-&gt;speak();
echo "\n";

$doggy = (new DogShelter)-&gt;adopt("Mavrick");
$doggy-&gt;speak();

This example will output:

Ricky meows
Mavrick barks

When it comes to contravariance, we’ll continue the previous example of Animal, Cat and Dog classes but will also include Food and AnimalFood classes and add an eat(AnimalFood $food) method to the Animal abstract class.


name = $name;
    }

    public function eat(AnimalFood $food)
    {
        echo $this-&gt;name . " eats " . get_class($food);
    }
}

Now to see the behavior of contravariance we’ll override the eat method in the Dog class to allow for any Food type object. The Cat class will remain unchanged.

 

name . " eats " . get_class($food);
    }
}

With the following example, you’ll see the behavior of contravariance:

adopt("Ricky");
$catFood = new AnimalFood();
$kitty-&gt;eat($catFood);
echo "\n";

$doggy = (new DogShelter)-&gt;adopt("Mavrick");
$banana = new Food();
$doggy-&gt;eat($banana);

The output will look like this:

Ricky eats AnimalFood
Mavrick eats Food

Now, what will happen if $kitty tries to eat the $banana?

The output will look like this:

Fatal error: Uncaught TypeError: Argument 1 passed to Animal::eat() must be an instance of AnimalFood, instance of Food given

Support for Weak References

With Weak References, you can retain a reference to an object without preventing it from being destroyed. Currently, Weak References are supported by the PHP extension pecl-weakref and they usually come handy when implementing cache-like structures.

The proposal for PHP 7.4 was to directly support weak referencing and make it very simple. So, the new API is different from the WeakRef class.

Here’s an example from Nikita Popov:

$object = new stdClass;
$weakRef = WeakReference::create($object);
var_dump($weakRef-&gt;get());
unset($object);
var_dump($weakRef-&gt;get());

For the first var_dump you’ll get object(stdClass)#1 (0) {} printed while the second var_dump will print NULL, because the object it references is destroyed.

Preloading

Here is how Dimitriy Stogov explains preloading:

On server startup – before any application code is run – we may load a certain set of PHP files into memory – and make their contents ‘permanently available’ to all subsequent requests that will be served by that server. All the functions and classes defined in these files will be available to requests out of the box, exactly like internal entities.

In the new PHP 7.4, preloading is controlled with just a single php.ini directive-opache.preload. This helps to specify one PHP file that will perform the task of preloading. Once this file is loaded it can preload other files by including them or by conducting the opcache_compile_file() function.

Here is an example of how preload is used in Zend Framework.

<?php
function _preload($preload, string $pattern = "/\.php$/", array $ignore = []) {
  if (is_array($preload)) {
    foreach ($preload as $path) {
      _preload($path, $pattern, $ignore);
    }
  } else if (is_string($preload)) {
    $path = $preload;
    if (!in_array($path, $ignore)) {
      if (is_dir($path)) {
        if ($dh = opendir($path)) {
          while (($file = readdir($dh)) !== false) {
            if ($file !== "." && $file !== "..") {
              _preload($path . "/" . $file, $pattern, $ignore);
            }
          }
          closedir($dh);
        }
      } else if (is_file($path) && preg_match($pattern, $path)) {
        if (!opcache_compile_file($path)) {
          trigger_error("Preloading Failed", E_USER_ERROR);
        }
      }
    }
  }
}

set_include_path(get_include_path() . PATH_SEPARATOR . realpath("/var/www/ZendFramework/library"));
_preload(["/var/www/ZendFramework/library"]);

However, there are some limitations for preloading. You can only preload classes without unresolved parents, traits, interfaces, and constant values.

In case the class doesn’t fulfill the condition, it gets stored in opcache SHM as part of the corresponding PHP script in the same way it would be stored without the preloading.

Also, note that you can preload only top-level entities that are not nested in the control structures.

Deprecations

Finally, here is a few deprecations for PHP 7.4:

    • Short open tags ?> are now deprecated
    • Left-associative ternary operator
1 ? 2 : 3 ? 4 : 5;  // deprecated
(1 ? 2 : 3) ? 4 : 5; // ok
1 ? 2 : (3 ? 4 : 5); // ok
    • Deprecative Curly Brace Syntax
 
$array[] = 3;
echo $array[2]; // prints 3
$array{} = 3; // Parse error: syntax error, unexpected '}'

PHP 7.4 for WordPress users

PHP and WordPress shown on the blue background

As stated by W3Techs, PHP is used by 78.9% of all websites whose server-side programming language the research team could detect. This means that PHP is one of the most popular server-side programming languages out there.

However, a lot of those websites run versions of PHP which are not supported. Moreover, 44% of users are still running the PHP 5 version.

Still, WordPress statistics indicate that a lot of users have switched to PHP 7.3 since 2019. Here is the chart of WP statistics from 2019:

A WP chart showing which PHP version is most used

As the chart shows, in 2019 the majority of users were either working with PHP 5.6 or PHP 5.5 and avoided the PHP 7.3 update. Only 13.1% used the new version, not to mention the percentage of WordPress 7.4 users who aren’t even visible in the chart.

In contrast, the statistics of August 2020 show different results. Here is the chart:

A WP chart showing which PHP is the most used (2020)

According to this chart, a lot of WordPress users have already switched to the newer versions of PHP. Today, a majority of 26% is using PHP 7.3 which is a huge improvement from last year.

Another good news is that the number of users represented in that pie chart who worked with PHP 7.4 is much bigger in 2020 than it was in 2019. 8.8 % have already switched to PHP 7.4.

Unfortunately, though, 24% are still running the PHP 5.5 version, significantly lowering the performance of their websites. So, if you’re one of the 24%, the upcoming section if for you.

Why should you update to PHP 7.4 ?

Not only does PHP 7.4 offer a bunch of useful features and improvements to the script, but it also makes your WordPress way faster. As the official PHP benchmark shows, you can execute two times more requests per second with PHP 7 than you can with PHP 5.6.

Another comparison was made by Christian Vigh who in his PHP performance analysis has shown that PHP 5.2 is 400% slower than PHP 7. 4. And Andrei Avram has shown that PHP 7.4 has a better execution time than PHP 7.3.
Here’s the test he conducted:



#!/usr/bin/env bash
 
test=$(cat << 'eot'
$time = microtime(true);
 
$array = [];
for ($i = 0; $i < 10000; $i++) {
    if (!array_key_exists($i, $array)) {
        $array[$i] = [];
    }
 
    for ($j = 0; $j < 1000; $j++) {
        if (!array_key_exists($j, $array[$i])) {
            $array[$i][$j] = true;
        }
    }
}
 
echo sprintf(
    "Execution time: %f seconds\nMemory usage: %f MB\n\n",
    microtime(true) - $time,
    memory_get_usage(true) / 1024 / 1024
);
eot
)
 
versions=( 5.6 7.0 7.1 7.2 7.3 7.4-rc )
 
for v in "${versions[@]}"
do
    cmd="docker run --rm -ti php:${v}-cli-alpine php -d memory_limit=2048M -r '$test'"
    sh -c "echo ${v} && ${cmd}"

done 

And here are the results. Don’t pay attention to the absolute results, just look at the differences.

 
5.6
Execution time: 4.573347 seconds
Memory usage: 1379.250000 MB

7.0
Execution time: 1.464059 seconds
Memory usage: 360.000000 MB

7.1
Execution time: 1.315205 seconds
Memory usage: 360.000000 MB

7.2
Execution time: 0.653521 seconds
Memory usage: 360.000000 MB

7.3
Execution time: 0.614016 seconds
Memory usage: 360.000000 MB

7.4-rc
Execution time: 0.528052 seconds
Memory usage: 360.000000 MB

While memory usage always stays the same, every new version of PHP outperforms the previous one when it comes to execution time.
That said, let’s now understand how you should upgrade to PHP 7.4.

Update your code

WordPress reports that it still runs PHP 7.3 as the default version as it has been stress-tested across WordPress.com. So, although PHP 7.3 stays the recommended version, you can easily upgrade to the latest version with very simple steps. We’ll show you the ropes by using the example of 10Web’s WordPress hosting. If you want a more detailed explanation, you can visit our blog on how to restart or change your PHP version.

From your 10Web hosting domain page go to the Hosting Services>Tools>PHP Engine Version section and find the PHP version you want to switch to — it couldn’t be easier. With just few clicks you can update your entire website to the latest PHP version.

Before, this method was only included in the eCommerce plan or Business plan. You could update either through an active plugin or a custom theme. Now, the PHP Version Switcher is available to all WordPress users so you can take advantage of this simple tool.

In short, if you want to significantly improve your website’s performance and get access to better features, it’s time to update your WordPress to PHP 7.4.

FAQs

Is PHP 7.4 stable?

Yes, PHP 7.4 is the latest, most stable version of PHP. It has been released and accessible for General Availability since November 28, 2019. Although this version already boosts the performance and makes the readability of the code better, the real milestone for PHP will be PHP 8.

Is PHP 7.4 backwards compatible?

Like with any other PHP update some of your plugins or themes might not be compatible with the latest version. So it’s better to check those before you update to the latest PHP version, or else PHP will throw deprecation warnings.

Is it necessary to upgrade to PHP 7.4?

Yes! If you want your page to improve its performance, become faster, and, in general, if you want to get access to all features and additions discussed in the article, then you need to upgrade!. With this version, the coding of your page will be much lighter and cleaner. That’s why it’s a good idea to go with the update.

However, take into consideration that some of your plugins or themes might not be compatible with the latest version, which might negatively affect your site during the update.

Is PHP 7.4 faster?

Christian Vingh and Andrei Avram along with many others have proven that PHP 7.4 is by far the fastest version of PHP. So, if you want your WordPress to improve its performance, this version is the best one by far. The next milestone will be PHP 8 which is expected to give your website a blazing speed.

In November 2019, PHP released its latest version, PHP 7.4. In this article, we’ve discussed some of its most useful features, namely Spread Operator in Array Expression, Support for Arrow Functions, Support for coalesce assign (??=) operator, Support of typed properties, Covariant Returns and Contravariant Parameters, Support for WeakReferences, Preloading, Deprecations. This latest version is sure to improve your website’s performance and functionality.So, it would be the right move to update your WordPress with PHP’s latest version.

Simplify WordPress with 10Web

Share article

Leave a comment

Your email address will not be published. Required fields are marked *

Your email address will never be published or shared. Required fields are marked *

Comment*

Name *