PHP 8.2 release
On December 8 PHP 8.2 was released, this new version includes many new features on the languages and some deprecations, you can see the complete list here, in this post we will try to explain some of the most important new features, not all of them.
Readonly classes
Readonly properties was introduced on PHP 8.1, A readonly
property can only be initialized once, and only from the scope where it has been declared. Any other assignment or modification of the property will result in an Error
exception.
In the case that you need a (quasi-)immutable class, declare all the properties one by one as readonly wasn’t an easy task.
Doing so will implicitly mark all instance properties of a class as readonly. Furthermore, it will prevent the creation of dynamic properties.
More info
https://wiki.php.net/rfc/readonly_classes
https://wiki.php.net/rfc/readonly_properties_v2
Disjunctive Normal Form (DNF) Types
In order to understand this new feature we shall respond the main question, What DNF means?, from wikipedia
In boolean logic, a disjunctive normal form (DNF) is a canonical normal form of a logical formula consisting of a disjunction of conjunctions; it can also be described as an OR of ANDs, a sum of products, or (in philosophical logic) a cluster concept.
Since PHP 8 the types has become a real important thing in PHP, now is possible to combine simple types into composite types. PHP allows types to be combined in the following ways:
- Intersection of class-types (interfaces and class names).
- Union of types.
These types are using to declaring a type for a parameter, property, or return types and enforce that values to accomplish the declared class/interface types restrictions.
On PHP 8 the Union type was introduced. From the PHP documentation
A union type accepts values of multiple different types, rather than a single one. Individual types which form the union type are joined by the |
symbol. Therefore, a union type comprised of the types T
, U
, and V
will be written as T|U|V
On PHP 8.1, intersection of types where introduced. From the PHP documentation
An intersection type accepts values which satisfies multiple class-type declarations, rather than a single one. Individual types which form the intersection type are joined by the &
symbol. Therefore, an intersection type comprised of the types T
, U
, and V
will be written as T&U&V
.
Before PHP 8.2, the combination of an Intersection and a Union type was not possible. Since PHP 8.2, DNF is possible and we can combine these types using parenthesis. Again, from the PHP documentation
On a Union type, If one of the types is an intersection type, it needs to be bracketed with parenthesis for it to written in DNF: T|(X&Y)
.
More info
https://wiki.php.net/rfc/dnf_types
https://en.wikipedia.org/wiki/Disjunctive_normal_form
https://www.php.net/manual/en/language.types.type-system.php#language.types.type-system.composite
https://php.watch/versions/8.0/union-types
https://php.watch/versions/8.1/intersection-types
Allow null
, false
, and true
as stand-alone types
What is null, true and false? From the PHP docs
The null type is PHP’s unit type, it has only one value: null
.
The bool type only has two values, and is used to express a truth value. It can be either true
or false
.
It’s very common to use null, false, true as return parameter, arguments to functions, that is why it became relevant to be able to declare these values as types and add more restrictions to the arguments, return values and even properties.
https://www.php.net/manual/en/language.types.null.php
https://www.php.net/manual/en/language.types.boolean.php
https://wiki.php.net/rfc/null-false-standalone-types
Constants in traits
From the RFCs
Traits are used for horizontal code reuse across classes, and currently allow the definition of methods and properties, but not constants. This means that it is not possible to define invariants expected by a trait in the trait itself. So currently, workarounds are required in some cases, such as defining constants in its composing class or an interface implemented by the composing class.
This new feature allow defining constants in traits in the same manner that is currently possible for properties, with the following use cases in mind.
https://wiki.php.net/rfc/constants_in_traits
Deprecate dynamic properties
Prior PHP 8.2 it was possible to add dynamic properties to a object, by default. In other words, it was possible to do this
class User { public $name; } $user = new User(); $user->last_name = 'Doe'; $user = new stdClass(); $user->last_name = 'Doe';
In order to have a PHP more type safe as you can see, this is not the way. As is mentioned in the RFC
“In modern code, this is rarely done intentionally.”
This new feature deprecates and later remove the creation of dynamic properties, unless the class explicitly allows dynamic properties (keep reading).
stdClass and __get/__set are not affected by this change.
More info
https://wiki.php.net/rfc/deprecate_dynamic_properties
New attributes
PHP 8 has introduced the Attributes feature. Attributes are meta-data to PHP functions, parameters, classes, class methods, constants, properties, closures, and even anonymous classes. This meta-data alters some defaults behaviors to PHP.
More info
https://php.watch/articles/php-attributes
In PHP 8.2 two new attributes have been added
#[AllowDynamicProperties]
This attributes is needed since the deprecation of dynamic properties, adding this attribute to a class it will allow the creation of dynamic properties on that class and their Childs.
More info
https://www.php.net/manual/en/class.allow-dynamic-properties.php
#[\SensitiveParameter]
It is very common to have variables with sensitive data that are added to stack trace or logs, PHP 8.2 includes this attribute to parameters to mark that is sensitive and it won’t be rendered on the output or logs of the traces. Use this in functions where you send passwords, credit card numbers, usernames, tokens and other sensitive values.
More info
https://www.php.net/manual/en/class.sensitive-parameter.php
https://php.watch/versions/8.2/backtrace-parameter-redaction
Deprecations and backward compatibility breaks
Quick review
Deprecated ${}
string interpolation.
This is deprecated
"Hello ${name}";
You need to do this instead
echo "Hello {$name}";
Functions strtolower
and strtoupper
are no longer locale-sensitive.
They now perform ASCII case conversion, as if the locale were “C”. Localized versions of these functions are available in the MBString extension.
Deprecated utf8_encode
and utf8_decode
functions.
As alternative to these functions you can use mbstring
, intl
, and iconv
extensions, those provide a robust and accurate functionality to detect and convert character encodings. mbstring
is used widely in modern PHP applications.
More info https://php.watch/versions/8.2/utf8_encode-utf8_decode-deprecated#replace
Others deprecations to have in mind https://www.php.net/manual/en/migration82.incompatible.php
PHP 8.0 No longer actively maintained
With the release of PHP 8.2, PHP 8.0 (released in 2020) is now marked as “security fixes only”.
More info
https://www.php.net/ChangeLog-8.php#PHP_8_2
https://php.watch/news/2022/12/php8.2-released
https://php.watch/versions/8.2
https://php.watch/articles/PHP-8.2
https://laravel-news.com/php-8-2-0
https://freek.dev/2382-introducing-php-82-all-new-features-and-changes