The PHP team released its version 8.1 of the language on November 25, 2021. Version 8.0 had arrived with a bunch of new features. Let’s see together what the next version has in store for us.
The spread operator for arrays containing string keys
It was already possible to do this since 7.4, but only with digital keys. The reason was that PHP didn’t handle duplicates. Now it’s done. You can therefore proceed as follows:
$weekBegin = ['Tuesday' => 2, 'Wednesday' => 3];
$weekMiddle = ['Thursday' => 4, 'Friday' => 5];
$weekEnd = ['Saturday' => 6, 'Sunday' => 7];
$week = ['Monday' => 1, ...$weekBegin, ...$weekMiddle, ...$weekEnd];
Array ( "Monday" => 1 "Tuesday" => 2 "Wednesday" => 3 "Thursday" => 4 "Friday" => 5 "Saturday" => 6 "Sunday" => 7 )
Fibers
Fibers are functions that cannot be interrupted, and which can be used to implement cooperative multitasking. In short, it’s a piece of code that you can pause and resume later. The feature has been added in PHP, but is still in the testing and development phase. Here is what gives a simple use of a Fiber:
$fiber = new Fiber(function (): void {
$value = Fiber::suspend('Suspended value');
echo "Value used to resume fiber: ", $value, "\n";
});
$value = $fiber->start();
echo "Value from fiber suspending: ", $value, "\n";
$fiber->resume('Hi again');
Value from fiber suspending: Suspended value Value used to resume fiber: Hi again
Explicit octal notation
You can now write numeric values directly in bytes. This notation is done with the prefix 0o:
echo (0o16 === 16 ? 'true' : 'false') . "\n";
echo (0o16 === 14 ? 'true' : 'false') . "\n";
echo 0o7716_1414;
false true 16573196
Final constants
The ability to declare final constants within a class is now possible. Very useful to prevent them from being overwritten by child classes:
ParentClass.php
class ParentClass
{
final const IMMUTABLE = 'Try to change me';
}
ChildClass.php
require "ParentClass.php";
class ChildClass extends ParentClass
{
public const IMMUTABLE = 'Okay, let me try';
}
index.php
require "ChildClass.php";
$child = new ChildClass();
Fatal error: ChildClass::IMMUTABLE cannot override final constant ParentClass::IMMUTABLE
The return type never
A function or method declared with type never indicates that it will not return a value and will throw an exception:
function neverReturn(): never
{
return 'never';
}
echo neverReturn();
Fatal error: A never-returning function must not return
Intersecting types as Method Arguments
It was already possible in the methods to propose several types for an argument, with the symbol “|” :
function sumNumbers(int|float $numberOne, int|float $numberTwo)
You can now use the symbol “&” to require for a method argument the intersection of 2 types:
function iterate(Iterator&Countable $iterator)
{
echo "This object contains " . $iterator->count() . " elements\n";
foreach ($iterator as $item) {
echo $item . "\n";
}
}
$days = ['Monday', 'Tuesday'];
iterate(new ArrayIterator($days));
This object contains 2 elements Monday Tuesday
If the value sent does not match, an exception will be thrown:
Fatal error: Uncaught TypeError: iterate(): Argument #1 ($iterator) must be of type Iterator&Countable, array given
Support for “new” in constructors
Constructor objects can now be created directly via a “new”. It is also possible to do this on any initialization, for example in annotations:
use Assert\All;
use Assert\Length;
use Assert\NotNull;
final class TestClass
{
private Generator $generator;
#[All(
new NotNull,
new Length(min: 5))
]
private string $name;
public function __construct(Generator $generator)
{
$this->generator = new Generator();
}
}
readonly property
Read-only properties cannot be changed after initialization, i.e. after they have been assigned a value:
TestClass.php
final class TestClass
{
public readonly string $name;
public function setName(string $name)
{
$this->name = $name;
}
}
index.php
include "TestClass.php";
$test = new TestClass();
$test->setName('John');
$test->setName('Jack');
In the example above, the first call will work, because the name property has not yet been initialized. On the other hand, the second call will throw an exception:
Fatal error: Uncaught Error: Cannot modify readonly property TestClass::$name
Enum classes
PHP 8.1 comes with a specific class type to declare your enumeration constants. It happens as follows:
Days.php
enum Days
{
case MONDAY;
case TUESDAY;
case WEDNESDAY;
case THURSDAY;
case FRIDAY;
case SATURDAY;
case SUNDAY;
}
index.php
include "Days.php";
echo 'First day of week = ' . Days::MONDAY->name;
print_r(Days::cases());
First day of week = MONDAY Array ( [0] => Days Enum([name] => MONDAY) [1] => Days Enum([name] => TUESDAY) [2] => Days Enum([name] => WEDNESDAY) [3] => Days Enum([name] => THURSDAY) [4] => Days Enum([name] => FRIDAY) [5] => Days Enum([name] => SATURDAY) [6] => Days Enum([name] => SUNDAY) )
Conclusion
There you go, you know everything about PHP version 8.1. To your keyboards to take control of all these new features! 😇