PHP 8.1 features, one year later
Closing on one year after PHP 8.1 publication, we can take a look at the published features, and how they are doing in current code.
Let’s take the list of ‘PHP Core’ from the New Features ¶.
Project corpus
We’ll use that against the Exakat corpus, with 2696 PHP open source projects. Out of those, 1511 were updated since last year, (56%). Those projects had a chance to update their code base to be compatible with PHP 8.1, and then, adopt those features.
Feature adoption
The PHP 8.1 features are all backward incompatible : adopting them means that the code cannot be run anymore on older version, including PHP 8.0. In the case of Open Source projects, with long eras of support, this means that the absolute figures will be much lower than against closed code.
The relative adoption of the features shows it popularity and is the most interesting part of this review.
That said, let’s dive.
Integer Octal Literal Prefix
014
being equivalent to 0o14
was adopted by 2 projects, including exakat itself for testing purposes. Generally speaking, octals are not common, being used by 34% of the projects, and primarily with mkdir() and related functions.
Array Unpacking with String Keys
This was not tracked by audits so far. It is easily hidden by decoded strings, dynamic code and databases responses. Some research is still needed in this area.
<?php $arr1 = [1, 'a' => 'b']; $arr2 = [...$arr1, 'c' => 'd']; //[1, 'a' => 'b', 'c' => 'd'] ?>
Named Argument After Argument Unpacking
This is not detected in any codes so far. For comparison, named parameters are used by 253 projects (16.7%).
<?php foo(...$args, named: $arg); ?>
full-path Key for File Uploads
This is not detected in any codes so far.
Enumerations
Enumeration are used by 151 projects (10%).
<?php enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; } ?>
Fibers
Fibers are used by 81 projects, so roughly 5.6 %.
<?php $fiber = new Fiber(function (): void { $value = Fiber::suspend('fiber'); echo "Value used to resume fiber: ", $value, PHP_EOL; }); $value = $fiber->start(); echo "Value from fiber suspending: ", $value, PHP_EOL; $fiber->resume('test'); ?>
First Class Callable Syntax
First class callable are used by 201 projects (13.3%).
Those are simpler syntax for closures creation.
<?php // traditional callable using string, array $fcc = strlen(...); $closure = Closure::fromCallable('strlen'); ?>
Intersection Types
Support for intersection types has been added.
Intersection types were adopted by 84 projects (5.6 %). Most of them are used with the poster child type of \Traversable&\Countable
. Other cases are Mock objects (thanks to Arnout Boks).
Never type
The never
type indicates that a function either exit(), throws an exception, or doesn’t terminate.
Never type were adopted by 43 projects, so roughly 2.9 %.
new in Initializers
New in initializers is the usage of new within PHP static expressions and define() calls for properties, and parameters.
New in initializer are used by 241 projects (15.9 %).
Readonly properties
Support for properties that can be written once, then only read has been added.
Readonly properties are now in use by 124 projects (8.2 %).
Final class constants
Final keyword is now compatible with constants. They are already used in 14 projects (0.9 %).
Final round up
The top 3 PHP 8.1 features are :
- New in initializers 15.9%
- First class callable 13.3%
- Enumerations 10%.
Then, come readonly, intersection type and fiber.
Recent statistics place PHP 8.1 adoption between 20% and 30%. With 15.9%, ‘new in initializer’ is actually adopted half the time, once PHP 8.1 has been upgraded. Enumerations are up to a 33%. These are good levels of adoption, one year later.
It seems to me that ‘new in initializer’ is a very productive feature, with the potential to upgrade significantly our code with the null object pattern. Yet, there are not many tutorials and blogs about them. Did we miss them ?