Introducing PHP 7.4: Performance, Features, Deprecations

Introducing PHP 7.4: Performance, Features, Deprecations

PHP 7.4 has finally arrived! This new version, released on November 28, 2019, is now available on all Hostinger servers. Developers can expect improvements in code readability, maintenance, and ease of use. Let’s look at some of the new features, performance tweaks, and other reasons why you should migrate to PHP 7.4.

Table of Contents: 

What Does PHP 7.4 Mean for You?

PHP continues to evolve with the newest PHP 7.4 update full of new features. Like we have seen in previous PHP 7 releases, performance and speed keep improving. One of the most exciting new features is preloading. It helps speed up script execution and introduces the ability to have faster and cleaner code, thanks to the simplification of common lines of code.

The good people responsible for PHP have heard their audience’s comments and requests and answered them completely. They have since been continuously changing code to be more intuitive and easier to switch between programming languages.

PHP is used in over 78.9% of all websites. According to W3techs, the most popular sites using PHP are Wikipedia, Pinterest, and Facebook, to name a few.

If we specifically look at WordPress sites running PHP, comparing PHP 5 and 7, we can see a double speed increase. WordPress-powered websites definitely gain the most by using the latest PHP version. Hostinger users can supercharge their WordPress sites with just a click of a button.

PHP Usage Statistics

See all these cool figures? This graph contains information about websites actively using PHP. Are 39,191,714 live websites enough to grab your attention? That’s how many are using PHP right now. Plus PHP 7.4 is already testing better than PHP 7.3 with improved performance and other quality of life improvements.

The graph below shows the overall benchmark test on new and old versions of PHP. Some of the criteria tested were ease of use, speed, and performance.

PHP Geometric Mean of All Results

Changing Your PHP Version

Ready to update? Thought so. Hostinger makes it as easy as ever with these four simple steps. You’ll be fiddling around with your new-and-improved PHP version in no time.

  1. Log into your Hostinger account and hit the Home button.
  2. On your Home page, scroll down to the Hosting section and click on the Manage icon.
  3. In the search box, type in PHP configuration and click on it.
  4. Select PHP 7.4 and click Save.

Enabling PHP 7.4 in Hostinger hPanel

Congrats! You now have the best and most up-to-date PHP version out there.

To check your current PHP version, all you need to do is go to the Hosting tab and check the left side panel for PHP version. If it’s anything less than 7.4, go ahead and update.

What’s New in PHP 7.4?

Since 2016, PHP7 has been releasing annual updates without fail. Each year they deliver new features, additions, and the possibility to write cleaner code that makes the language more reliable and user-friendly for those who run it on their websites.

Let’s dig in and take a closer look at some of the changes that were made in PHP 7.4. For a full list check out the changelog here.

Preloading

Let’s talk about code. When using a framework or library, its files have to be loaded and linked on every request. Preloading is when you can load frameworks and libraries into OPCache. It allows for the server to load PHP files and store them in memory during startup and have them available for any future requests. Talk about getting things going quick!

Preloading is run by a specific php.ini directive: opache.preload.This has the PHP script compiler and executes when the server starts up. It can also be used to preload more files and choose to either include or compile them.

This is awesome – however, if the source of the preloaded files is ever changed, the server must be restarted. The preloaded files also remain cached in the OPCache memory forever.

That said, these preloaded files will continue to be available for any future requests in case you ever need to use them again.

Spread Operator in Array Expressions

Back when PHP 5.6 was released, PHP began supporting argument unpacking (spread operator) but now, with 7.4, we are able to use this feature with an array expression. Argument unpacking is a syntax for unpacking arrays and traversables into argument lists. And, in order to do so, it only needs to be prepended by … (3 dots.) That’s it.

Let’s look at this example:

$animals = ['dog', 'cat'];
$animalkingdom = ['lion', 'elephant', ...$animals, 'giraffe'];
// [‘lion’, ‘elephant’, ‘dog’, ‘cat’, ‘giraffe’];

We can now expand an array from anywhere we want in another array, by simply using the Spread Operator syntax.

Here is a longer example:

$num1 = [1, 2, 3];
$num2 = [...$num1]; // [1, 2, 3]
$num3 = [0, ...$num1]; // [0, 1, 2, 3]
$num4 = array(...$num1, ...$num2, 111); // [1, 2, 3, 1, 2, 3, 111]
$num5 = [...$num1, ...$num1]; // [1, 2, 3, 1, 2, 3]

Not only that, but you can also use it in a function. Check out this example:

function getNum() {
  return ['a', 'b'];
}
$num6 = [...getNum(), 'c']; // ['a', 'b', 'c']

$num7 = [...new NumIterator(['a', 'b', 'c'])]; // ['a', 'b', 'c']

function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$num8 = [...arrGen()]; // [11, 12, 13, 14]

In addition, you are now able to unpack arrays and generators that are returned by a function directly into a new array.

A code example would look like this:

function getAnimals(){
	return ['dog', 'cat', 'elephant'];
}
$num1 = [...getAnimals(), 'lion', 'tiger', 'giraffe'];

And with PHP 7.4, it would print:

array(6) {
	[0]=>
	string(3) "dog"
	[1]=>
	string(3) "cat"
	[2]=>
	string(8) "elephant"
	[3]=>
	string(4) "lion"
	[4]=>
	string(5) "tiger"
	[5]=>
	string(7) "giraffe"
}

With this new array expression, spread operators should have way better performance over the 7.3 array_merge. This is because the spread operator is a language structure while array_merge is a function. Also because spread operator supports objects implementing traversable and array_merge only supports arrays.

It’s important to note that you can only use indexed arrays since string keys are not supported. If used, a recoverable error will be shown on the screen once a string key is found.

Another great benefit of 7.4 is the removal of the array_merge. Say goodbye to the dreaded index shift!

For example, let’s look at this long-winded array merge below:

$array = [‘banana, ‘orange’];
$array[2] = ‘orange’;
$array[1] = ‘apple’; //shifting
var_dump($array); 
// prints 
array(3) {
	[0]=>
	string(6) "banana"
	[1]=>
	string(5) "apple"
	[2]=>
	string(6) "orange"

Another benefit of 7.4 is the generator function. A generator function works just like a normal function, except instead of returning a value, it yields as many values as it needs to.

Check out the code example below:

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

Weak References

Now PHP 7.4 has a WeakReference class, which is not to be confused with the class WeakRed or the Weakref extension.

WeakReferences let the programmer recall a reference to an object. This is useful because it doesn’t prevent the object from being destroyed. They are helpful for implementing cache-like structures.

WeakReference {
/* Methods */
public __construct ( void )
public static create ( object $referent ) : WeakReference
public get ( void ) : ?object
}

Contravariant Parameters and Covariant Returns

Currently, PHP uses mostly invariant parameter types and return types. This means that if a method has a parameter or return type of X, then the subtype parameter or return type must also be type X.

Now, PHP 7.4 allows covariant (ordered from specific to generic) and contravariant (reversing the order) on parameter and return types.

Here are examples of both:

Covariant return type example:

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

Contravariant parameter type example:

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

Typed Properties 2.0

Since PHP 5, type hints have been an available feature allowing you to specify the type of variable that is expected to be passed to a function or class. In the PHP 7.2 migrations, the addition of the object data type gave hope that more would be available in the future. The future is now.

In the new 7.4, PHP is able to support the following type list:

bool, int, float, string, array, object, iterable, self, parent
any class or interface name
?type // where "type" may be any of the above

Note that the parent type can be used in classes and does not need to have a parent consistent with the parameter and return type.

Also, note that void and callable are not supported. Void was removed because it was not useful and had unclear semantics; Callable – because its behavior was context-dependent.

Let’s check out some more examples.

Here is a class written for PHP 7.3:

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

In PHP 7.4, without sacrificing any type-safety, a class can now be written as simple as:

class User {
    public int $id;
    public string $name;
 
    public function __construct(int $id, string $name) {
        $this->id = $id;
        $this->name = $name;
    }
}

Here are some examples of all the types 7.4 now supports:

class Example {
  
    public int $scalarType;
    protected ClassName $classType;
    private ?ClassName $nullableClassType;

    // Types are also legal on static properties
    public static iterable $staticProp;

    // Types can also be used with the "var" notation
    var bool $flag;

    // Typed properties may have default values (more below)
    public string $str = "foo";
    public ?string $nullableStr = null;

    // The type applies to all properties in one declaration
    public float $x, $y;
    // equivalent to:
    public float $x;
    public float $y;
}

Arrow Functions 2.0

Anonymous functions in PHP tend to be wordy and lengthy, even when they are only performing simple operations. This is partially due to a large amount of syntactic boilerplate and the need to manually import used variables.

This makes code that uses simple closures confusing to read and even harder to understand.

Let’s look at some code that you would use with PHP 7.3:

function array_values_from_keys($arr, $keys) {
    return array_map(function ($x) use ($arr) { return $arr[$x]; }, $keys);
}

Here is the more concise syntax of PHP 7.4:

function array_values_from_keys($arr, $keys) {
    return array_map(fn($x) => $arr[$x], $keys);
}

Therefore, arrow functions now have this simple form:

fn(parameter_list) => expr

Below you can see an example of two functions $fn1 (7.3) and $fn2 (7.4) side by side. They have the same outcome but look different:

$y = 1;
$fn1 = fn($x) => $x + $y;


$fn2 = function ($x) use ($y) 
{
    return $x + $y;
};

This will also work if the arrow functions are nested:

$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;

Here the outer function captures $z. Then, the inner function also captures $z from the outer function. With 7.4, the outer scope can become available in the inner function. This is something 7.3 wasn’t able to do.

The arrow function syntax allows for a variety of functions, such as variadics, default values, parameter and return types, as well as by-reference passing and returning, all while keeping a clean, readable look. Below are all the valid arrow functions now available:

fn(array $x) => $x;
fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;

One thing to note is that arrow functions have the lowest precedence. See the example:

fn($x) => $x + $y
// is
fn($x) => ($x + $y)
// not
(fn($x) => $x) + $y

Deprecations

There are many deprecations happening with the move to 7.4. The following list is a short overview of the functions targeted for deprecation. You can find a more detailed explanation here:

  • The real type
  • Magic quotes legacy
  • array_key_exists() with objects
  • FILTER_SANITIZE_MAGIC_QUOTES filter
  • Reflection export() methods
  • mb_strrpos() with encoding as 3rd argument
  • implode() parameter order mix
  • Unbinding $this from non-static closures
  • hebrevc() function
  • convert_cyr_string() function
  • money_format() function
  • ezmlm_hash() function
  • restore_include_path() function
  • allow_url_include ini directiv

Some important ones to note are the following two-step deprecations.

Changing the Precedence of a Concatenation Operator

Currently the precedence of ‘.’, ‘+,’ and ‘-‘ operators are all equal. Any combination of these operators will simply be solved left-to-right.

Let’s look at this PHP 7.3 code:

echo "sum: " . $a + $b; 
// would be evaluated left-to-right
echo ("sum: " . $a) + $b;
// could also look like this

With PHP 7.4, ‘+’ and ‘-’ take precedence over ‘.’ so the additions and subtractions would always be performed before the string. This looks like the following:

echo "sum: " . $a + $b; 
// would be executed as if the code were as follows.
echo "sum :" . ($a + $b);

This two-step proposal aims to be less error-prone and more intuitive. PHP 7.4 currently is in the first stage with a deprecation notice of un-parenthesized expressions of ‘+’, ‘-,’ and ‘.’ while waiting for the final vote/change happening in PHP 8.

Left-Associative Ternary Operator

Unlike most other languages, the ternary operator in PHP is left-associative rather than right-associative. This is not only uncommon but also confusing for programmers who switch between different languages. PHP 7.4 proposes to remove the left-associativity and requires the use of parentheses instead.

Let’s take a look at the code below:

return $a == 1 ? 'one'
     : $a == 2 ? 'two'
     : $a == 3 ? 'three'
     : $a == 4 ? 'four'
               : 'other';

In most other languages it would be interpreted as:

return $a == 1 ? 'one'
     : ($a == 2 ? 'two'
     : ($a == 3 ? 'three'
     : ($a == 4 ? 'four'
               : 'other')))

While in PHP, it is instead interpreted as:

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

This can lead to errors because it’s generally not what was intended.

Through a separate two-step proposal, PHP 7.4 has implemented the explicit use of parentheses as a deprecation warning and will hopefully carry out a compile runtime error in future versions.

Conclusion

Just in time for the holidays, PHP 7.4 brings new features and quality of life improvements for all PHP developers.

WordPress websites will definitely benefit from these improvements and their users can expect faster execution times and less memory usage when using PHP 7.4 compared to the previous versions.

With the addition of first-class property type declarations and type hinting, arrow merging functions, and ridiculously better speed, the 7.4 will surely improve both the pace and quality of your workflow.

Author
The author

Linas L.

Linas started as a customer success agent and is now a full-stack web developer and Technical Team Lead at Hostinger. He is passionate about presenting people with top-notch technical solutions, but as much as he enjoys coding, he secretly dreams of becoming a rock star.