PHP 8 was released on 26 November, 2020 and has brought us a complete package of extraordinary features with rich language improvements. 

It’s time to experience some of the most exciting add-ons that makes PHP faster and more reliable.

This blog post is all about the features and improvements in one of the most awaited tech spells of 2020, PHP 8.

Just in Time Compiler (JIT)

The most decorated feature going to be offered in the new PHP 8 is the Just-in-time (JIT) compiler.

“PHP JIT is implemented as an almost independent part of OPcache. It may be enabled/disabled at PHP compile-time and run-time. When enabled, the native code of PHP files is stored in an additional region of the OPcache shared memory and op_array→opcodes[].handler(s) keep pointers to the entry points of JIT-ed code.”, the RFC proposal stated about JIT.

Let’s explore the new dimensions that are going to open after the JIT feature and what is the difference between the upcoming JIT vs conventional OPcache approach.

To better acknowledge what JIT serves for the PHP, it is important to discuss the 4 stage execution process of PHP.

  • Tokenizing or Lexing:

In this very first stage, the interpreter reads the PHP code and builds a set of tokens.

  • Parsing:

The interpreter ensures that the script matches the syntax principles and uses tokens to build an Abstract Syntax Tree (AST) – a hierarchical graph of the Program’s layout.

  • Compilation:

The interpreter traverses the AST and translates its nodes into low-level opcodes, which are numeric identifiers holding the information about the type of function performed by the Zend VM.

  • Interpretation:

Opcodes after being interpreted, run on the Zend VM as a final procedure.

The following image shows a visual representation of the basic PHP execution process.

 

Fundamental PHP Execution Process of PHP

So, what makes PHP work faster with the mainstream Opcache based execution process? And how is the execution process going to change after the arrival of JIT?

  • The OPcache Extension

As an interpreted language, when a PHP script runs, the interpreter parses, compiles, and executes the code again and again on each request cycle. This may cause an immense waste of processing resources and increases the execution time.

Here comes the role of OPcache extension into play.

According to the RFC proposal, “OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.”,

With OPcache extension, the PHP interpreter undergoes the aforementioned 4 stage process only for the 1st execution. As PHP byte codes are located in shared memory space, they are readily available as low-level intermediate source and can be run on the Zend VM immediately.

  • Preloading

OPcache has been recently enhanced with the deployment of the preloading feature in PHP 7.4. Preloading makes it possible to hold certain types of scripts in OPcache memory before the execution of any application code. But this feature is limited for not making tangible performance improvement for mainstream web applications.

JIT opens a new way forward, in which previous features failed to open.

  • The Just in Time Compiler (JIT)

JIT is free from any additional Intermediate Representation (IR) representation, as it uses Dynamic Assembler for code generation engines (DynASM) to produce native code directly from PHP byte-code.

In simple words, JIT transforms the important segments of the intermediate language into machine language. By dodging the lengthy process of compilation, it can cast considerable improvements in performance and memory domains.

PHP 8 Improvements and New Features

Apart from JIT, there is much more to improve and evolve in PHP 8. Below are some upcoming features that would make PHP more handy and enhanced. 

Constructor Property Promotion

Due to contemporary discussions regarding the improvement of the object-oriented model in PHP, the Constructor Property Promotion RFC comes with a more simple syntax that will further reduce the complexity of the property declaration.

This proposal only applies to specific parameters with public, protected, and private prefixes or keywords.

For now, all properties have to be recurred multiple times (at least four times), before getting in use with the object. For instance:


Informed by the author of the RFC, Nikita Popov, we have to write the property name at least four times during three different events:

  • The property declaration
  • The constructor parameters
  • The property assignment.

This syntax is not specifically practical in cases involving classes with a rich number of properties and more descriptive prefixes.

This methodology manages to combine both the constructor and the parameter declaration. In PHP 8, we have more practical methods of declaring parameters which results in the changes in the aforementioned code as:


It’s just a simple transformation of the syntax that is going to introduce. But it will reduce the number of code lines you have to write to transform objects.

Due to this simple change, we can now use the Reflection API to examine the property before the execution cycle. It will benefit in the way that enhanced properties will appear the same way as separately confined properties, and enhanced constructor arguments will appear as mainstream constructor arguments.


Inheritance

There are no restrictions in using inheritance in combination with enhanced parameters. Anyway, there’s not a specific dependency between parent and child class constructors. In general practice, the method must be compatible with the parent method but this rule does not obey the constructor. For instance:


What’s Not Allowed With Enhanced Properties

Enhanced properties are permitted in constructors and traits having no abstract, but several restrictions needed to be mentioned here.

Abstract Constructors

Enhanced properties are not allowed in abstract classes and interfaces:


Nullability

One of the most obvious changes is linked with nullability. In recent practices, when we choose a type that wasn’t explicitly nullable but has a default null value, the type was implicitly considered as null. But it is necessary to note that with property types, there is an absence of implicit activity because enhanced parameters need a declaration of property, thus the nullable type must be explicitly declared. For instance the following RFC scenario:


Callable Type

Callable is not supportive of properties, as we are not permitted to use the callable type in enhanced properties:


Prohibition of var Keyword

Because of the restriction to use visibility, keywords can be used with enhanced parameters, declaring constructor properties with the var keyword are not permitted. Consider the following RFC example:


Duplications’ Restriction

We can merge enhanced properties and explicit properties in the same class, but properties cannot be declared more than once:


Prohibition of Variadic Parameters

The reason for this restriction is the difference in declared type and the variadic parameter, which is an array:


Abstract Trait Methods

Traits are methodologies for code reuse in single inheritance languages like that of PHP. Normally, they are used to define methods that can be called in multiple classes.

A trait can also include abstract methods. These methods can only declare the method’s signature, but the method’s implementation must be carried out inside the class domain using the trait.

“Traits support the use of abstract methods to impose requirements upon the exhibiting class,” as per the PHP manual.

It also means that the signatures of the methods must be the same. In simple words, the type and the number of arguments must be the same.

Incompatible Signatures

In PHP, if method signatures do not match the inheritance, an error routine occurs that pushes either a fatal error or a warning depending on the cause or origin of the error.

Below is an example of an inheritance error:


In an older version of PHP, the aforementioned code would show the following error:

Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a) in /path/to/your/test.php on line 7

A function in a child’s class with the wrong signature would show a warning alert. For instance the code from RFC:


In an older version of PHP, the aforementioned code would show the following warning:

Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Now, the new feature reformed to always show a fatal error for wrong method signatures. With PHP 8, the aforementioned code would show the alert:

Fatal error: Declaration of C2::method(int $a) must be compatible with C1::method(array $a) in /path/to/your/test.php on line 7

Negative Index Arrays

In PHP, if an array begins with a negative index, the following indices will start from 0. For instance:


In older versions, the result appears as:


Now, the new reforms propose that the second index would start with start_index + 1, whatever the value of start_index is.

In PHP 8, the aforementioned code would show:


With PHP 8, arrays starting with a negative index change their behavior. Read more about backward incompatibilities in the RFC.

Union Types 2.0

Union types accept a variety of values. For now, PHP doesn’t entertain union types, (Except the ?Type syntax and the special iterable type).

In older versions, union types could only be limited to phpdoc annotations. For instance the RFC code below:


On the contrary, the Union 2.0 support involves accommodation for union types in function signatures, so that we there’ll need to depend on inline documentation. For instance:


Consistent Type Errors

When trying to declare illegal type parameters, both built-in and user-defined functions respond differently.

User-defined functions push a TypeError, but internal functions respond in different ways, depending on the nature of the false attempt. Whatever the response is but the most probable and normal response is to show a warning and return null. For example in the older version:


This will cause the system to return the following warning:

Warning: strlen() expects parameter 1 to be string, object given in /path/to/your/test.php on line 4

NULL

If strict_types is active, the response would be different and results in a TypeError.

To remove this collision, the RFC binds APIs to always produce a ThrowError in case of a parameter type contradiction.

In PHP 8, the aforementioned code shows the following error:

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($str) must be of type string, object given in /path/to/your/test.php:4

Stack trace:

#0 {main}

thrown in /path/to/your/test.php on line 4

Throw Expression

In PHP, a throw is a hard-coated syntax part, so it’s not practical as an expression.

The new reform introduces the methodology to convert the throw statement into an expression so that it can be used as an expression.

For instance:


Weak Maps

A weak map is a store of data (objects) with weakly referenced keys so that they are not refrained from collecting garbage values.

That’s why the new reforms propose a WeakMap class to declare objects to use weak map keys that can be vanished from the weak map, if they don’t have any references to the key object.

For instance:


In new PHP 8, the aforementioned code would respond as the following result:


If you forget to set the object, the key will itself from the weak map:


The result would be:


Upcoming PHP Functions

PHP 8 introduces different new functions:

strstr and strpos 

In older versions, strstr and strpos were considered to be the traditional options for developers to find a needle inside any string. Problem is, both functions aren’t considered very natural and their handling can be difficult for aspiring PHP developers. For instance:


In the aforementioned example !== comparison operator restricts the users to get an error in case of a needle with zero position.

str_contains 

Furthermore, the RFC introduces a new function that enables the user to search inside a string using the str_contains function:


It is an easier and less vulnerable practice to errors.

str_starts_with and str_ends_with

In addition to this, two new functions allow searching for a needle inside a given string: str_starts_with and str_ends_with.

These new functions determine if a given string starts or ends with another string, for instance:


Both functions return false if $needle is lengthier than $haystack.

get_debug_type

get_debug_type is a newly introduced PHP function that returns the type of a variable. This new function works in the same way as the gettype function, but besides, get_debug_type returns native type names & resolves class names.

This RFC example portrays two easy examples to better acknowledge the difference between the new get_debug_type() function and the mainstream gettype()function.

The first one shows gettype:


With PHP 8, we can use get_debug_type, instead:


The following table shows returning values of get_debug_type and gettype:


CONCLUSION

In this article, we tried to cover all the key improvements and enhancements expected in the new PHP 8. The hottest feature, no doubt is the Just in Time Compiler, but there’s much more to offer by PHP 8 and we are super excited for the launch.PHP 8 was released on 26 November, 2020 and has brought us a complete package of extraordinary features with rich language improvements. 

It’s time to experience some of the most exciting add-ons that makes PHP faster and more reliable.

This blog post is all about the features and improvements in one of the most awaited tech spells of 2020, PHP 8.

Leave a Reply