Pull to refresh

Introducing PHP 7.4: Performance, Features, Deprecations

Reading time7 min
Views3.4K

PHP evolves continuously and they just released their latest PHP 7.4 update. Performance and speed keep advancing, as we have already been proved in the past PHP 7 releases. Preloading is one of the most thrilling new updates. It quickens script execution and makes code cleaner and faster due to the simplified common lines of code.


PHP is an important element in the world wide web and is used in over 79% of all websites. Well-known websites like Facebook, Wikipedia, WordPress and much more are using PHP.
We can see a double speed increase when looking at WordPress sites running PHP and comparing PHP 5 and 7. While using the latest PHP version out there — WordPress powered websites gain the most.





Currently, there are around 40 mln. websites using PHP. This graph illustrates the performance of the websites that use PHP actively. Overall, PHP 7.4 is looking quite good over PHP 7.3 with better performance on top of introducing the FFI capabilities, the preload feature, and other improvements.
The following graph compares the overall benchmark test results on 7.4 and older PHP versions.





What’s New in PHP 7.4?


PHP7 has been releasing constant yearly updates since 2016. Various new features, ability to write cleaner code to make the language more trustworthy and convenient if you run it on your website. Let’s catch a glimpse of some modifications that were made with the PHP 7.4 release.
You can find the full list in their changelog.


Preloading


Preloading is when you’re able to load frameworks and libraries into the OPCache. It’s a truly convenient feature since files have to be loaded and linked on every request while using a framework or libraries. Loading the PHP files and storing it in memory at startup to have them ready for any coming requests? Preloading does that!


Preloading is controlled by a single new php.ini directive: opcache.preload. Using this directive we can specify a single PHP file — which will perform the preloading task. Once loaded, this file is then fully executed — and may preload other files, either by including them or by using the opcache_compile_file() function.


As I’ve already mentioned, preloaded files will stay cached in opcache memory indefinitely. Modification of their corresponding source files won’t have any effect without another server restart.


Therefore, in case you should want to use these preloaded files again — it will be accessible for any forthcoming requests.


Spread Operator in Array Expressions


PHP started to maintain argument unpacking (spread operator), way back on PHP 5.6 release. Now, with 7.4, we can use this feature with an array expression. The syntax for unpacking arrays and Traversables into argument lists is called argument unpacking. And to make that happen, you only need to prepend it by 3 dots (…).


Take a look at this instance:


$tropicalfruits = ['banana', 'orange'];
$fruits = ['apple', 'pear', ...$tropicalfruits, 'plum'];
// [‘apple’, ‘pear’, ‘banana’, ‘orange’, ‘plum’];

Now it’s possible to expand an array from anywhere in another array, by using the Spread Operator syntax.


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]
<source>
<p>In addition, you can use it in a function. Like in this example:</p>
<source lang="php">
function getNum() {
  return ['x', 'y'];
}
$num6 = [...getNum(), 'z']; // ['x', 'y', 'z']
 
$num7 = [...new NumIterator(['x', 'y', 'z'])]; // ['x', 'y', 'z']
 
function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$num8 = [...arrGen()]; // [11, 12, 13, 14]

Now you’re also able to unpack arrays and generators that are returned by a function straight into a new array:


function getFruits(){
return ['apple', 'orange', 'banana'];
}
$num1 = [...getFruits(), 'plum', 'grapefruit', 'watermelon'];

With PHP 7.4 it would return this:


array(6) {
[0]=>
string(3) "apple"
[1]=>
string(3) "orange"
[2]=>
string(8) "banana"
[3]=>
string(4) "plum"
[4]=>
string(5) "grapefruit"
[5]=>
string(7) "watermelon"
}

Using this array expression, spread operators should have way better performance over the 7.3 array_merge. This is due to the spread operator being a language structure, while array_merge is a function. Another reason is that the spread operator supports the object's implementation of traversable when array_merge only supports arrays.


Additional amazing and really convenient feature that came with 7.4 is the removal of the array_merge indexed arrays. This is because string keys are not supported. Index shift no more!


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

Another PHP 7.4 advantage over the older versions is the generator function. Difference between generator function and normal function is that, a generator function yields as many values as it needs to instead of returning a value. So, any function containing yield is a generator function:


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

Weak References


PHP 7.4 has a WeakReference class which lets you retain a reference to an object which does not prevent the object from being destroyed. It is useful for implementing cache-like structures.
Be aware to not mistake WeakReference with the WeakRef class or Weakref extension.


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

Contravariant Parameters and Covariant Returns


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


With PHP 7.4 it offers to enable contravariant (reversing the order) and covariant (ordered from specific to generic) on parameter and return types.


Let’s take a look at both:


Covariant return type:


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

Contravariant parameter type:


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

Typed Properties 2.0


Type hints have been an available feature since PHP 5. It allows you to specify the type of variable that is intended to be passed to a function or class.


In the PHP 7.2 migrations, the supplement of the object data type gave hope that more would be available in the future.


In PHP 7.4, it is possible to support the type list below:


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

Parent type can be used in classes and doesn’t need to have a parent constant with the parameter and return type.


Besides, callable and void are not supported. Callable was removed because its behavior was context-dependent; void, because it was not useful and had unclear semantics.


Take a look at the examples below.


A PHP 7.3 class:



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 classes are simple as that:



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

PHP 7.4 supported types:



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


Arrow functions in PHP often are redundant and prolonged, even in case of performing simple actions. This is partly because of a great deal of syntactic boilerplate, and partly because of the necessity to imply used variables manually.


This makes a code with a minor functionality complex and difficult to read.


This would be an anonymous function in PHP 7.3:


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

And this is an easy to read arrow function in PHP 7.4:


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

Hence, that arrow functions are this straightforward:


fn(parameter_list) => expr

There you can see two functions $fn1 and $fn2. Code looks different but functions pass identical result.


$c = 1;
$fn1 = fn($a) => $a + $c;
 
 
$fn2 = function ($a) use ($c)
{
    return $a + $c;
};

This will also surely work with nested arrow functions:


$c = 1;
$fn = fn($a) => fn($b) => $a * $b + $c;

This is something out of 7.3 capabilities. The parent function acquires $c while the child function also acquires $c from the parent function. In PHP 7.4, the external range can become accessible in the child function.


Arrow functions syntax let us use variadics, default values, parameter and return types, as well as by-reference passing and returning, while letting us keep a clear, understandable appearance.


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

Also it’s worth indicating that arrow functions have the lowest priority:


fn($a) => $a + $b
// is
fn($a) => ($a + $b)
// not
(fn($a) => $a) + $b

Deprecations


As for now the precedence of `.`, `+` and `-` operators are equal. Any combination of these operators will be solved from left-to-right.


Check out this 7.3 code below:


echo "sum: " . $x + $y;
// would be evaluated left-to-right
echo ("sum: " . $x) + $y;
// or like this

With PHP 7.4 the additions and subtractions would always be performed before the string, due to `+` and `-` taking priority over `.`:


echo "sum: " . $x + $y;
// would be performed as if the code were as below.
echo "sum :" . ($x + $y);

This two-step suggestion claims to be less fallible and more instinctive.


Left-Associative Ternary Operator


Contrary to most other languages, the ternary operator in PHP is left-associative rather than right-associative. PHP 7.4 intention is that instead of the use of left-associativity — start using the parentheses. So it wouldn’t be unusual and puzzling for programmers who switch between different languages.


Let’s see the example below:


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

In the majority of other languages it would be read as:


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

While in PHP, it is instead read as:


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

Due to the fact that it’s usually not what was planned, this could cause errors.


Conclusion


PHP 7.4 elevates new handy features and conveniences for every PHP programmer out there.


WordPress websites and their users will definitely benefit from these improvements. Reduced memory usage and rapid execution times are just a few of many advancements while using PHP 7.4 in contrast with previous releases.


PHP 7.4 will certainly enhance both the speed and quality of your working process with the extension of arrow merging functions, first-class property type declarations and type hinting, and insanely better speed.

Tags:
Hubs:
+3
Comments0

Articles