Knowledge Base Hub

Browse through our helpful how-to guides to get the fastest solutions to your technical issues.

Home  >  Domain Name & DNS Issues  >  Introduction to PHP 7.4 – Features, Deprecations and Speed
Top Scroll

Introduction to PHP 7.4 – Features, Deprecations and Speed

 13 min

The next PHP 7 minor version, PHP 7.4 is expected to be released to the General Availability on November 28th, 2019. So, you should learn about the exciting additions and new features that will make PHP faster as well as highly reliable.

Although PHP 7.4 helps in boosting the performance and improving code reliability, PHP 8 will be the actual landmark for PHP performance because of the approval of JIT inclusion.

In this article, you are going to learn about some of the most interesting features and changes being expected with PHP 7.4.

What’s New in PHP with PHP 7.4?

This post will cover the changes and features that need to be added to the language with the final release of PHP 7.4:
Forget array_merge: Get Spread Operator in Array Expression with PHP 7.4

Argument unpacking is available since PHP 5.6 a syntax for unpacking arrays and Traversables into argument lists.

For unpacking an array or a Traversable, it has to be prepended by … (3 dots), as below:

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

Now this PHP 7.4 RFC suggests extending this feature to array definitions:

$arr = [...$args];

The first benefit of Spread Operator in array expression stated is related to performance. In fact, the RFC doc states:

Spread operator should perform better than array_merge. This isn’t just because the spread operator is a language structure and array_merge is a function, but also because compile time optimization can be performant for constant arrays.

Spread operator supports any traversable objects while the array_merge function supports only arrays and this is the biggest advantages of spread operator.

Check below the example of argument unpacking in array expression:

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

In case, you run this code with in PHP 7.3 or earlier, PHP displays a Parse error:

Parse error: syntax error, unexpected '...' (T_ELLIPSIS), expecting ']' in /app/spread-operator.php on line 3

Instead, PHP 7.4 might return an array as below:

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

As per the RFC you can expand the same array multiple times. Furthermore, the Spread Operator syntax can be used everywhere in the array, as normal elements can be added before or after the spread operator. So the following code might work as expected:

$arr1 = [1, 2, 3];
$arr2 = [4, 5, 6];
$arr3 = [...$arr1, ...$arr2];
$arr4 = [...$arr1, ...$arr3, 7, 8, 9];

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

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

PHP 7.4 displays the output in the following array:

array(6) {
	[0]=>
	string(3) "red"
	[1]=>
	string(5) "green"
	[2]=>
	string(4) "blue"
	[3]=>
	string(4) "pink"
	[4]=>
	string(6) "violet"
	[5]=>
	string(6) "yellow"
}

 

It is also possible to use the generator syntax:

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

But it isn’t allowed to unpack arrays passed by reference. Check the following example:

$arr1 = ['red', 'green', 'blue'];
$arr2 = [...&$arr1];

If you try to unpack an array by reference, PHP displays the following Parse error:

Parse error: syntax error, unexpected '&' in /app/spread-operator.php on line 3

Well, if the elements of the first array are stored by reference, you will find them in the second array, as well. Here is an example:

$arr0 = 'red';
$arr1 = [&$arr0, 'green', 'blue'];
$arr2 = ['white', ...$arr1, 'black'];

And here is what you get with PHP 7.4:

array(5) {

               [0]=>
               string(5) "white"
               [1]=>
               &string(3) "red"
               [2]=>
               string(5) "green"
               [3]=>
               string(4) "blue"
               [4]=>
               string(5) "black"
}

 

The proposal of Spread operator passed with 43 to 1 votes.

Arrow Functions 2.0 (Short Closures)

Anonymous functions in PHP are considered to be quite wordy and hard to implement and maintain. Therefore, RFC has proposed to introduce the shorter and clean syntax of the arrow functions (or short closures), that should allow you to clean up your PHP code importantly.

Consider the following example:

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

PHP 7.4 allows using a more concise syntax, and the function above can be rewritten as below:

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

Currently, anonymous functions (closures) can derive variables mentioned in the parent scope due to the use of language construct, as shown below:

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

But using the PHP 7.4, variables mentioned in the parent scope are completely captured by value (implicit by-value scope binding). So the whole function seen above can be written on a single line:

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

You can use the variable mentioned in the parent scope in the arrow function exactly as you used use($var), and it’s not possible to alter a variable from the parent scope.

A great improvement to the language is the new syntax as it enables to build highly readable and maintainable code.

It is also possible to use parameter and return types, variable-length argument lists (variadic functions), default values, we can pass and return by reference, etc. Finally, you can use short closures in class methods and they can use the $this variable similar to regular closures.

This RFC has got the approval with 51 to 8 votes, and so you can expect it to be a part of PHP 7.4 additions.

Null Coalescing Assignment Operator

The coalesce operator (??) that is included with PHP 7 is useful when you need to use a ternary operator in conjunction with isset(). If it exists, it returns the first operand and is not NULL. Or else, it returns the second operand. Below is an example:

$username = $_GET['user'] ?? ‘nobody’;

The working of this code is quite straightforward: it fetches the request parameter and sets a default value if it doesn’t exist. Hope you have got a clear idea about that line, but what if you have longer variable names as in the below example from the RFC?

$this->request->data['comments']['user_id'] = $this->request->data['comments']['user_id'] ?? 'value';

Ultimately, this code can be a bit difficult to maintain. So, in order to help developers to write more instinctive code, this RFC suggests the introduction of the null coalescing assignment operator (??=). So, rather than writing the previous code, you can write the following:

$this->request->data['comments']['user_id'] ??= ‘value’;

In case the value of the left-hand parameter is null, then the value of the right-hand parameter is used.

Remember that, while the coalesce operator is a comparison operator, ??= is an assignment operator.

This proposal was approved with 37 to 4 votes.

Typed Properties 2.0

With argument type declarations, or type hints, you can specify the type of a variable that is expected to be passed to a function or a class method. Type hints has been available since PHP 5 and you can use them with the object data type since PHP 7.2. In PHP 7.4 the type hinting has enhanced by including the support for first-class property type declarations. Check the basic example below:

class User {
public int $id;
public string $name;
}

The exception of void and callable supports all the types:

public int $scalarType;
protected ClassName $classType;
private ?ClassName $nullableClassType;

Below is the explanation by RFC about why void and callable are not supported:

The void type is not supported, as it is not useful and has unclear semantics.

The callable type is not supported, as its behavior is context dependent.

So it is safe to use bool, int, float, string, array, object, iterable, self, parent, any class or interface name, and nullable types (?type).

Types can be used on static properties as below:

public static iterable $staticProp;

They are also permitted with the var notation:

var bool $flag;

You can set default property values, which must match the declared property type, but only nullable properties can have a default null value:

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

All properties will have the same type applied in a single declaration:

public float $x, $y;

What happens if you make an error on the property type? Check the following code:

class User {
public int $id;
public string $name;
}

$user = new User;
$user->id = 10;
$user->name = [];

In the above code, you declared a string property type, but you set an array as property value. In such a case, you get the below Fatal error:

Fatal error: Uncaught TypeError: Typed property User::$name must be string, array used in /app/types.php:9

This RFC has received an approval with 70 to 1 votes.

Weak References

PHP 7.4 will introduce the WeakReference class with this RFC that enables programmers to retain a reference to an object that avoids preventing the object itself from being destroyed.

Using an extention such as pecl-weakref, currently PHP supports Weak References. But, the new API is different from the WeakRef class that is documented.

This RFC received 28 to 5 votes.

Covariant Returns and Contravariant Parameters

A property of class hierarchies is called as variants that describe the effect of types of a type constructor on subtypes.

In general, a type constructor can be:

Invariant: if the type of the subtype is limited by the type of the super-type.
Covariant: if the ordering of types is prevented (types are ordered from more specific to more generic).
Contravariant: in case the order is reversed (types are ordered from more generic to more specific).

Right now, PHP has mostly invariant parameter and return types but have some exceptions. But RFC has proposed to allow covariance and contravariance on parameter types and return types, along with offering several examples of code.

Below is an example of covariant return type:

interface Factory {
function make(): object;
}

class UserFactory implements Factory {
function make(): User;
}

And here is an example of contravariant parameter type:

interface Concatable {
function concat(Iterator $input);
}

class Collection implements Concatable {
// accepts all iterables, not just Iterator
function concat(iterable $input) {/* . . . */}
}

This RFC received votes from 39 to 1.

Preloading

This was proposed by Dmitry Stogov and it is expected to bring a significant boost in performance. In preloading, libraries and frameworks are loaded into the OPCache at module initialization.

Below is explanation of how preloading works as per Dmitry:

When the server starts up – prior to running any application code – you might 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. Similar to internal entities, all the functions and classes defined in these files will be available to requests out of the box.

Prior to any application, these files are loaded on server startup and are executed and remain available for any future requests. This helps in improving the performance.

A specific php.ini directive: opcache.preload controls the preloading. A PHP script to be compiled and executed at server start-up is specified by this directive. It is possible to preload additional files by using this file, either including them or via the opcache_compile_file() function.

But there’s a disadvantage. Even, the RFC clearly states:

preloaded files remain cached in opcache memory forever. Therefore, if their corresponding source files are modified, they won’t have any effect without another server restart.

But all the functions mentioned in the preloaded file will be permanently loaded into PHP function and class tables and will stay available for every future request. This will help in enhancing the performance, though these improvements will vary considerably.

New Custom Object Serialization Mechanism

This is another proposal approved with a large majority of votes.

Currently, there are two different mechanisms for custom serialization of objects in PHP:

• The __sleep() and __wakeup() magic methods
• The Serializable interface

With both these options, there are issues that help in giving rise to complex and unreliable code. The new serialization method should prevent these issues by offering two new magic methods, __serialize() and __unserialize(), that combines two existing mechanisms.

This proposal has received 20 to 7 votes.

Deprecations

The following functions/functionalities will be deprecated with PHP 7.4:

Change the Precedence of the Concatenation Operator

Today, in PHP the “+” and “-” arithmetic operators, and the “.” string operator are left associative and have the same precedence.

As an example, consider the following line:

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

In PHP 7.3 this code creates the following warning:

Warning: A non-numeric value encountered in /app/types.php on line 4

The reason is that the concatenation is evaluated from left to right. It is similar to writing the following code:

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

This RFC will help in changing the precedence of operators, giving “.” a lower precedence than “+” and “-” operators, so that additions and subtractions will always be performed prior to the string concatenation. That line of code should be equivalent to the below:

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

This is a two-step proposal:

• Starting from version 7.4, PHP should emit a contempt notice while encountering an unparenthesized expression with “+”, “-” and “.”.
• The actual change of precedence of these operators should be added with PHP 8.

Both proposals have been approved with a large majority of votes.

Deprecate Left-Associative Ternary Operator

In PHP the ternary operator, unlike many other languages, is left-associative. But this can be confusing for programmers that switch between different languages.

Currently, in PHP the following code is correct:

$b = $a == 1 ? 'one' : $a == 2 ? 'two' : $a == 3 ? 'three' : 'other';

It’s interpreted as:

$b = (($a == 1 ? 'one' : $a == 2) ? 'two' : $a == 3) ? 'three' : 'other';

This can lead to errors as it may not be what you are intending to do. So, RFC has proposed to deprecate and remove the use of left-associativity for ternary operators and force developers to use parentheses.

This is the next two-step proposal:

• Starting from PHP 7.4, housed ternaries without clear use of parentheses will display a deprecation warning.
• Starting from PHP 8.0, you might get will be a compile runtime error.

This proposal has been received approved with 35 to 10 votes.

PHP 7 Performance

The above numbers are especially discouraging as those come from a performance point of view, as PHP 7 has seen to be significantly faster. Here are a few stats:

• As per official PHP benchmarks PHP 7 enables the system to run twice as many request per second as compared to the PHP 5.6 at almost half of the latency.
• According to the PHP performance comparison by Christian Vigh, PHP 5.2 is 400% slower as compared to PHP 7.
• As per Andrei Avram, PHP 7.4 offers faster execution times and less memory in comparison to PHP 7.3
• Phoronix also did some early benchmark tests with PHP 7.4 Alpha and found that it was slightly faster than PHP 7.3.

How to Install and Run PHP 7.4 on Docker?

Fortunately, you don’t require to manually compile and configure PHP 7.4. In case you already have Docker installed on your system, you simply need to install the unofficial PHP-FPM 7.4 Docker Image and run your tests from the command line in few seconds.

In case you want to run your PHP 7.4 code in your browser, you also need to install an Nginx or Apache image. But don’t worry. Just follow the developer’s directions. You need to simply copy and paste the commands from the Docker Image page to your command line tool, and you’re ready to go.

Conclusion

In this post, we covered a good number of changes and additions that we can expect with the release of PHP 7.4.

For our Knowledge Base visitors only
Get 10% OFF on Hosting
Special Offer!
30
MINS
59
SECS
Claim the discount before it’s too late. Use the coupon code:
STORYSAVER
Note: Copy the coupon code and apply it on checkout.