PHP 8 has been officially released to the General Availability on November 26, 2020! Show
This new major update brings many optimizations and powerful features to the language. We’re excited to drive you through the most interesting changes that will allow us to write better code and build more robust applications. PHP 8.0 Announcement AddendumAre you ready? Let’s dive in! PHP JIT (Just in Time Compiler)The most acclaimed feature coming with PHP 8 is the Just-in-time (JIT) compiler. What is JIT all about? The RFC proposal describes JIT as follows:
So, how did we get to JIT, and what is the difference between JIT vs OPcache? To better understand what JIT is for PHP, let’s take a quick look at how PHP executes the source code to the final result. The PHP execution is a 4 stage process:
The following image shows a visual representation of the basic PHP execution process. Basic PHP execution processSo, how does OPcache make PHP faster? And what changes in the execution process with JIT? The OPcache ExtensionPHP is an interpreted language. This means, when a PHP script runs, the interpreter parses, compiles, and executes the code over and over again on each request. This may result in wasting CPU resources and additional time. This is where the OPcache extension comes in to play:
With OPcache enabled, the PHP interpreter goes through the 4 stage process mentioned above only when the script runs for the first time. Since PHP bytecodes are stored in shared memory, they are immediately available as low-level intermediate representation and can be executed on the Zend VM right away. PHP execution process with OPcache enabledAs of PHP 5.5, the Zend OPcache extension is available by default, and you can check if you have it correctly configured by simply calling Suggested reading: How to Improve PHP Memory Limit in WordPress. Zend OPcache section in a phpinfo pagePreloadingOPcache has been recently improved with the implementation of preloading, a new OPcache feature added with PHP 7.4. Preloading provides a way to store a specified set of scripts into OPcache memory “before any application code is run.” Still, it doesn’t bring tangible performance improvement for typical web-based applications. You can read more about preloading in our introduction to PHP 7.4. With JIT, PHP moves a step forward. JIT — The Just in Time CompilerEven if opcodes are low-level intermediate representation, they still have to be compiled into machine code. JIT “doesn’t introduce any additional IR (Intermediate Representation) form,” but uses DynASM (Dynamic Assembler for code generation engines) to generate native code directly from PHP byte-code. In short, JIT translates the hot parts of the intermediate code into machine code. Bypassing compilation, it’d be able to bring considerable improvements in performance and memory usage. Zeev Surasky, co-author of the PHP JIT proposal, shows how much calculations would be faster with JIT: But, would JIT effectively improve WordPress performance? JIT for Live Web AppsAccording to the JIT RFC, the just in time compiler implementation should improve PHP performance. But would we really experience such improvements in real-life apps like WordPress? The early tests show that JIT would make CPU-intensive workloads run significantly faster. However, the RFC warns:
With JIT enabled, the code wouldn’t be run by the Zend VM, but by the CPU itself, which would improve the calculation speed. Web apps like WordPress also rely on other factors like TTFB, database optimization, HTTP requests, etc. Relative JIT contribution to PHP 8 performance (Image source: PHP 8.0 Announcement Addendum)So, we shouldn’t expect a significant boost in PHP execution speed when it comes to WordPress and similar apps. Nevertheless, JIT could bring several benefits for developers. According to Nikita Popov:
So, while JIT will hardly bring huge improvements to WordPress performance, it’ll be upgrading PHP to the next level, making it a language many functions could now be written directly in. The downside would be the greater complexity that can increase maintenance, stability, and debugging costs. According to Dmitry Stogov:
The proposal to include JIT in PHP 8 passed with 50 to 2 votes. PHP 8 is here! 🚀 Check out our deep dive into the new features!Click to Tweet PHP 8 Improvements and New FeaturesApart from JIT, we can expect many features and improvements with PHP 8. The following list is our handpicked selection of the upcoming additions and changes that should make PHP more reliable and efficient. Constructor Property PromotionAs a result of an ongoing discussion about improving object ergonomics in PHP, the Constructor Property Promotion RFC proposes a new and more concise syntax that will simplify the property declaration, making it shorter and less redundant. This proposal only relates to promoted parameters, i.e. those method parameters prefixed with public, protected, and private visibility keywords. Currently, all properties have to be repeated several times (at least four times) before we can use them with objects. Consider the following example from the RFC:
According to Nikita Popov, the RFC author, we have to write the property name at least four times in three different places: the property declaration, the constructor parameters, and the property assignment. This syntax is not particularly usable, especially in classes with many properties and more descriptive names. This RFC proposes to merge the constructor and the parameter definition. So, as of PHP 8, we have a more usable way of declaring parameters. The code seen above can change as shown below:
And that’s it. So we have a new way to promote properties that are shorter, more readable, and less prone to errors. According to Nikita:
The property declaration is transformed as we’d explicitly declared those properties, and we can use the Reflection API to introspect property definitions before the execution (see Desugaring):
InheritanceWe don’t have any limitations in using inheritance in conjunction with promoted parameters. Anyway, there’s not a particular relation between parent and child class constructors. According to Nikita:
Here is an example:
What’s Not Allowed With Promoted PropertiesPromoted properties are allowed in non-abstract constructors and traits, but there are several limitations worth mentioning here. Abstract ConstructorsPromoted properties are not allowed in abstract classes and interfaces:
NullabilityOne of the most notable constraints is related to nullability. Previously, we used a type that wasn’t explicitly nullable. But with a null default value, the type was implicitly nullable. But with property types, we don’t have this implicit behavior because promoted parameters require a property declaration, and the nullable type must be explicitly declared. See the following example from the RFC:
Callable TypeAs callable is not a supported type for properties, we are not allowed to use the callable type in promoted properties:
The var Keyword Is Not AllowedOnly a visibility keyword can be used with promoted parameters, so declaring constructor properties with the
No Duplications AllowedWe can combine promoted properties and explicit properties in the same class, but properties cannot be declared twice:
Variadic Parameters Are Not AllowedThe reason here is that the declared type is different from the variadic parameter, which is actually an array:
Further ReadingsFor a closer view at Costructor Property Promotion, listen to this interview with Nikita Popov. For an in-depth overview of object ergonomics in PHP, see this post and the following interview with Larry Garfield. Validation for Abstract Trait MethodsTraits are defined as “a mechanism for code reuse in single inheritance languages such as PHP.” Typically, they are used to declare methods that can be used in multiple classes. A trait can also contain abstract methods. These methods simply declare the method’s signature, but the method’s implementation must be done within the class using the trait. According to the PHP manual,
This also means that the signatures of the methods must match. In other words, the type and the number of required arguments need to be the same. Anyway, according to Nikita Popov, author of the RFC, signature validation is currently enforced only spottily:
The following example from Nikita relates to the first case (not enforced signature):
With that being said, this RFC proposes to always throw a fatal error if the implementing method is not compatible with the abstract trait method, regardless of its origin:
This RFC has been unanimously approved. Incompatible Method SignaturesIn PHP, inheritance errors due to incompatible method signatures throw either a fatal error or a warning depending on what is causing the error. If a class is implementing an interface, incompatible method signatures throw a fatal error. According to Object Interfaces documentation:
Here is an example of an inheritance error with an interface:
In PHP 7.4, the code above would throw the following error:
A function in a child class with an incompatible signature would throw a warning. See the following code from the RFC:
In PHP 7.4, the code above would simply throw a warning:
Now, this RFC proposes to always throw a fatal error for incompatible method signatures. With PHP 8, the code we saw earlier above would prompt the following:
Arrays Starting With a Negative IndexIn PHP, if an array starts with a negative index (
In PHP 7.4 the result would be the following:
Now, this RFC proposes to change things so that the second index would be In PHP 8, the code above would result in the following array:
With PHP 8, arrays starting with a negative index change their behavior. Read more about backward incompatibilities in the RFC. Union Types 2.0Union types accept values that can be of different types. Currently, PHP doesn’t provide support for union types, except for the Before PHP 8, union types could only be specified in phpdoc annotations, as shown in the following example from the RFC:
Now, the Union types 2.0 RFC proposes to add support for union types in function signatures, so that we won’t rely on
inline documentation anymore, but would define union types with a
As explained by Nikita Popov in the RFC,
Union types support all available types, with some limitations:
You can read more about Union Types V2 in the RFC. Consistent Type Errors for Internal FunctionsWhen passing a parameter of illegal type, internal and user-defined functions behave differently. User-defined functions throw a
This would result in the following warning:
If This situation would lead to a number of problems well explained in the RFC’s issues section. To remove these inconsistencies, this RFC proposes to make the internal parameter parsing APIs to always generate a
In PHP 8, the code above throws the following error:
throw ExpressionIn PHP, This RFC proposes to convert the See the following examples from the RFC:
Weak MapsA weak map is a collection of data (objects) in which keys are weakly referenced, meaning that they are not prevented from being garbage collected. PHP 7.4 added support for weak references as a way to retain a reference to an object that doesn’t prevent the object itself from being destroyed. As pointed out by Nikita Popov,
That’s why this RFC introduces a In long-running processes, this would prevent memory leaks and improve performance. See the following example from the RFC:
With PHP 8, the code above would produce the following result (see the code in action here):
If you unset the object, the key is automatically removed from the weak map:
Now the result would be the following:
For a closer look at Weak maps, see the RFC. The proposal was unanimously approved. Trailing Comma in Parameter ListTrailing commas are commas appended to lists of items in different contexts. PHP 7.2 introduced trailing commas in list syntax, PHP 7.3 introduced trailing commas in function calls. PHP 8 now introduces trailing commas in parameter lists with functions, methods, and closures, as shown in the following example:
This proposal passed with 58 to 1 votes. Allow ::class syntax on objectsTo fetch the name of a class, we can use the
With PHP 8, This proposal was unanimously approved. Attributes v2Attributes, also known as annotations, are structured metadata that can be used to specify properties for objects, elements, or files. Until PHP 7.4, doc-comments were the only way to add metadata to declarations of classes, functions, etc. The Attributes v2 RFC introduces PHP attributes, defining them as a form of structured, syntactic metadata that can be added to declarations of classes, properties, functions, methods, parameters, and constants. Attributes are added before the declarations they refer to. See the following examples from the RFC:
Attributes can be added before or after a doc-block comment:
Each declaration may have one or more attributes, and each attribute may have one or more associated values:
See the RFC for a more in-depth overview of PHP attributes, use cases, and alternative syntax. Named ArgumentsNamed arguments provide a new way of passing arguments to a function in PHP:
We can pass named arguments to a function by simply adding the parameter name before its value:
We are also allowed to use reserved keywords, as shown in the example below:
But we are not allowed to pass a parameter name dynamically. The parameter must be an identifier, and the following syntax is not allowed:
According to Nikita Popov, the author of this RFC, named arguments offer several advantages. First off, named arguments will help us write more understandable code because their meaning is self-documenting. The example below from the RFC is self-explanatory:
Named arguments are order-independent. This means that we are not forced to pass arguments to a function in the same order as the function signature:
It’s also possible to combine named arguments with positional arguments:
Another great advantage of named arguments is that they allow specifying only those arguments we want to change. We don’t have to specify default arguments if we don’t want to overwrite default values. The following example from the RFC makes it clear:
Named arguments can be used with PHP attributes, as shown in the following example from the RFC:
However, passing positional arguments after named arguments is not allowed and will result in a compile-time error. The same happens when you pass the same parameter name twice. Named arguments are handy with class declarations because constructors usually have many parameters, and named arguments provide a more “ergonomic” way to declare a class. For a closer view at Named Arguments, with constraints, backward incompatibilities, and several examples, see the Named Arguments RFC. Nullsafe OperatorThis RFC introduces the nullsafe operator In short-circuit evaluation, the second operator is evaluated only if the first operator does not
evaluate to Consider the following examples from the RFC:
If See the nullsafe operator RFC for additional examples, exceptions, and future scope. Saner String to Number ComparisonsIn previous PHP versions, when making a non-strict comparison between strings and numbers, PHP first casts the string to a number, then performs the comparison between integers or floats. Even if this behavior is quite useful in several scenarios, it may produce wrong results that may also lead to bugs and/or security issues. Consider the following example from the RFC:
PHP 8 introduces Saner string to number comparisons, aiming to make string to number comparisons more reasonable. In the words of Nikita Popov,
The following table compares the behavior of string to number comparison earlier PHP versions and in PHP 8: Comparison | Before | After ------------------------------ 0 == "0" | true | true 0 == "0.0" | true | true 0 == "foo" | true | false 0 == "" | true | false 42 == " 42" | true | true 42 == "42foo" | true | false Read more about the many implications of this change and how string to number comparisons change in PHP 8 in the official RFC from Nikita Popov. Saner Numeric StringsIn PHP, strings containing numbers fall into three categories:
Numeric strings and leading-numeric strings are treated differently depending on the operation performed. For example:
String offsets, arithmetic operations, increment and decrement operations, string-to-string comparisons, and bitwise operations also lead to different results. This RFC proposes to:
For a more in-depth overview of numeric strings in PHP 8, with code examples, exceptions, and backward compatibility issues, see the RFC. Match Expression v2The new To understand the difference between the two control structures, consider the following
We can now get the same result as the code above with the following
A significant advantage of using the new The
For additional examples and cases of use, see the Match expression v2 RFC and the PHP documentation. Stricter Type Checks for Arithmetic/Bitwise OperatorsIn previous PHP versions, applying arithmetic and bitwise operators to an array, resource, or non-overloaded object was allowed. Anyway, the behavior was sometimes inconsistent. In this RFC, Nikita Popov shows how unreasonable that behavior could be with a simple example:
Nikita explains how applying arithmetic or bitwise operator to arrays, resources, or non-overloaded objects led to different results:
With PHP 8, things change, and the behavior is the same for all arithmetic and bitwise operators: Throw a New PHP FunctionsPHP 8 brings several new functions to the language: str_containsBefore PHP 8, strstr and strpos were the typical options for developers to search for a needle inside a given string. The problem is that both functions aren’t considered very intuitive, and their usage can be confusing for new PHP developers. See the following example:
In the example above, we used the
Furthermore, several frameworks provide helper functions to search for a value inside a given string (see Laravel Helpers documentation as an example). Now, this RFC proposes the introduction of a new function allowing to search inside a string:
Its
usage is pretty straightforward. So, thanks to
Which is more readable and less prone to errors (see this code in action here). The str_starts_with() and str_ends_with()In addition to the These new functions check if a given string starts or ends with another string:
Both functions return According to Will Hudgins, the author of this RFC,
Thanks to them, we could now avoid using sub-optimal and less intuitive functions like
You can see this code in action here. This RFC has been approved with 51 to 4 votes. get_debug_type
That’s a good improvement for the language, as The RFC provides two useful examples to understand the difference between the new
With PHP 8, we could use
The following table shows returning values of
Additional RFCsHere is a quick list of additional approved improvements coming with PHP 8:
PHP 8 Performance BenchmarksIf you’re wondering how fast PHP 8 is, we have the answer. We benchmarked 20 PHP platforms/configurations on 7 different PHP versions (5.6, 7.0, 7.1, 7.2, 7.3, and 8.0). PHP 8.0 emerged as the winner in most platforms that support it, including WordPress and Laravel. Compiled PHP benchmarks of the top platformsFor instance, WordPress on PHP 8.0 can handle 18.4% more requests per second than PHP 7.4. Likewise, Laravel on PHP 8.0 can run 8.5% more requests per second than PHP 7.3. If your website or app is fully compatible with PHP 8.0, you should plan to update your server’s environment to PHP 8.0 as soon as possible. You (and your users) will definitely appreciate its performance benefits. However, please test your site thoroughly before updating. You can read our PHP benchmarks article for more information, such as detailed performance data, insights, and pretty graphs! PHP 8 has been released to the GA and brings lots of optimizations and features to the language. 🚀 Check out our deep dive into PHP 8!Click to Tweet SummaryWhat a ride! In this post, we covered the most interesting optimizations and features coming with PHP 8. The most awaited of which is surely the Just in Time compiler, but there’s so much more with PHP 8. Make sure to bookmark this blog post for your future reference. 🤓 Now it’s your turn: are you ready to test the new PHP features? Which one is your favorite? Drop a line in the comments section below. Save time, costs and maximize site performance with:
All of that and much more, in one plan with no long-term contracts, assisted migrations, and a 30-day-money-back-guarantee. Check out our plans or talk to sales to find the plan that’s right for you. |