PHP 8.1 released and has a major update of the PHP language. In this article we will list some of the new features comes with this release.
According to PHP manual here are some of the new features comes in PHP 8.1.
New Features:
Enumerations
From the biggest features in this release in the enum syntax. You may saw the enum syntax in languages such as C++ or Java. The enum syntax enables to declare a set of predefined values to choose from, i.e validating that a value falls in a set of values.
Before PHP 8.1 we have to define a class of constants like so:
class Gender { const MALE = 'male'; const FEMALE = 'female'; }
Now in PHP 8.1 using enum:
enum Gender { case Male; case Female; } function validateGender(Gender $gender) {}
Readonly Properties
A new keyword “readonly” to mark that the property is readonly. Readonly property can’t be changed after initialization. This is the same as marking a property as “private” with no setter function.
class Listing { public readonly bool Is_Featured; public function __construct(bool $Is_Featured) { $this->Is_Featured= $Is_Featured; } }
Before PHP 8.1 to achieve same behavior we have to use private without setter:
class Listing { private bool Is_Featured; public function __construct(bool $Is_Featured) { $this->Is_Featured= $Is_Featured; } public function getIsFeatured(): bool { return $this->Is_Featured; } }
Readonly properties perfect for modeling value objects and data-transfer objects.
Using “New” In Initializers
Before PHP 8.1 you may encountered scenarios when passing default values to initialization functions such as constructors, but this leads to extra check for missing or null arguments.
For example:
class User { private UserDetails $details; public function __construct(?UserDetails $details = null) { $this->details = $details ?? new DefaultDetails; } }
In this example if the we create an instance of this class without providing constructor parameter, the DefaultDetails will be created.
Now in PHP 8.1 this syntax can be shortened by allowing to use the “new” expression inside constructors:
class User { public function __construct( private UserDetails $details = new DefaultDetails, ) {} }
This is same as the above code.
Multiple arguments also allowed:
public __construct( $details = new DefaultDetails, $languages = new DefaultLanguages('ar'), $schools = new DefaultSchools(), ) { }
Intersecting Types
This is another important feature which allows to use multiple type constraints separated by “&” symbol when declaring that a variable must satisfy multiple types at the same time. This is the same as using an if statement to check that a variable meets multiple scenarios.
This example from the RFC:
function count_and_iterate(Iterator $value) { if (!($value instanceof Countable)) { throw new TypeError('value must be Countable'); } foreach ($value as $val) { echo $val; } count($value); }
In this function we provided a value that can be iterated, by declaring it with “Iterator”, but also we need to make sure that it can be counted using the php count() function, so we make an extra check using:
if (!($value instanceof Countable)) { throw new TypeError('value must be Countable'); }
In PHP 8.1 we can combine both types so that the provided value can satisfy Iterator and Countable interfaces:
function count_and_iterate(Iterator&Countable $value) { foreach ($value as $val) { echo $val; } count($value); }
As shown here i added the Iterator&Countable altogether.
New Return Type “never”
A new return type also introduced in this release which is the “never” return type. To understand the use of this return type, consider when making functions that doesn’t use the return statement but instead echo something to the browser and exist using exit() or die() functions.
For example:
function redirect() { echo "<script> window.location.href='http://'; </script>"; die(); }
In PHP 8.1 the return type can be specified as “never”:
function redirect() : never { echo "<script> window.location.href='http://'; </script>"; die(); } function redirectToPage(): never { redirect('/login'); echo 'Sometext'; // <- dead code detected by static analysis }
The RFC proposed any function that use an expression like throw(), exit() or die() must mark the function return type as never or noreturn type. This is helpful for static analysis tools to discover this.
Declaring Class Constants with final
In PHP 8.1 it’s possible to declare a class constant as final. This prevents the child classes to override this constant.
For example, before 8.1 PHP doesn’t throw an error when override class constant
class Foo { public const XX = "foo"; } class Bar extends Foo { public const XX = "bar"; // No error }
PHP 8.1:
class Foo { final public const XX = "foo"; } class Bar extends Foo { public const XX = "bar"; // Fatal error }
Keyed Arrays Unpacking
Also this concept called argument destruction in languages like “Javascript”. Array parameters unpacking was first introduced in PHP 7.4 but in this time the unpacking supported only on numeric array keys using the spread operator. In PHP 8.1 unpacking of string keyed arrays in now possible.
$array = [...$array1, ...$array2]; // Approximately the same as: $array = array_merge($array1, $array2);
$arrayA = ['a' => 1]; $arrayB = ['b' => 2]; $result = array_merge(['a' => 0], $arrayA, $arrayB); // ['a' => 1, 'b' => 2]
This is same as:
$arrayA = ['a' => 1]; $arrayB = ['b' => 2]; $result = ['a' => 0, ...$arrayA, ...$arrayB]; // ['a' => 1, 'b' => 2]
Other Features In PHP 8.1:
- New
fsync
andfdatasync
functions. - New
array_is_list
function. - New
array_is_list
function.
Performance Improvements In PHP 8.1:
- JIT backend for ARM64 (AArch64)
- Inheritance cache (avoid relinking classes in each request)
- Fast class name resolution (avoid lowercasing and hash lookup)
- timelib and ext/date performance improvements
- SPL file-system iterators improvements
- serialize/unserialize optimizations
Deprecated Features In PHP 8.1:
Serializable
interface deprecated.$GLOBALS
variable restrictions.- MySQLi: Default error mode set to exceptions.
- Implicit incompatible float to int conversion is deprecated.
- finfo Extension:
file_info
resources migrated to existing finfo objects. - IMAP: imap resources migrated to
IMAP\Connection
class objects. - FTP Extension: Connection resources migrated to
FTP\Connection
class objects. - GD Extension: Font identifiers migrated to
GdFont
class objects - Passing null to non-nullable internal function parameters is deprecated.
- HTML entity en/decode functions process single quotes and substitute by default.
Refer to PHP manual website for other features.