PHP 8.2 will be released on November 24, 2022. In this post, we will explore the features, performance improvements, changes and deprecations in this release.
Readonly classes – Readonly classes rfc
In php 8.1 we have Readonly properties in 8.2 adding syntax to make all class properties read-only at once.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # PHP 8.1 class Post { public function __construct( public readonly string $title, public readonly Author $author, public readonly string $body, public readonly DateTime $publishedAt, ) {} } # PHP 8.2 readonly class Post { public function __construct( public string $title, public Author $author, public string $body, public DateTime $publishedAt, ) {} } |
Functionally, making a class read-only is exactly the same as making every property read-only; but it will also prevent dynamic properties from being added to a class:
1 2 3 4 5 6 | $post = new Post(/* … */); $post->unknown = 'wrong'; // Sẽ báo lỗi: Uncaught Error: Cannot create dynamic property Post::$unknown |
Note that you can only extend from readonly classes if the subclass is also a readonly class .
Deprecate dynamic properties – Don’t use dynamic properties rfc
I’d say this is a change for the better, but it will take a bit of a hit. Dynamic properties are deprecated in PHP 8.2 and will generate an ErrorException
in PHP 9.0 :
1 2 3 4 5 6 7 8 9 | class Post { public string $title; } // Thuộc tính name không được khai báo và ide sẽ cảnh báo đoạn này $post->name = 'Name'; |
New random extension – New random extension rfc
PHP 8.2 adds a new random number generator to fix many of the problems with the previous one: it’s more efficient, more secure, easier to maintain, and doesn’t rely on global state; eliminates a bunch of hard to spot errors when using PHP’s random functions.
There is a new class called Randomizer
, which accepts a randomizer engine
.
1 2 3 4 5 6 7 8 | $rng = $is_production ? new RandomEngineSecure() : new RandomEngineMt19937(1234); // Randomizer construct với tham số là một Randomizer engine $randomizer = new RandomRandomizer($rng); $randomizer->shuffleString('foobar'); |
null
, true
, and false
as standalone types rfc
PHP 8.2 adds three new types null, true and false that can be considered valid types . Common examples are PHP’s built-in functions, where false is used as the return type when an error occurs. Example in file_get_contents:
1 2 | file_get_contents(/* … */): string|false |
Before PHP 8.2, you could use false with other types as a conjugate; but now it can also be used as a standalone type:
1 2 3 4 5 6 7 | function alwaysFalse(): false { return false; } // tương tự với null và true |
Disjunctive Normal Form Types – DNF Types rfc
DNF types allow us to combine union (|) and intersection (&) types, following a strict rule: intersection types must be grouped with brackets. In fact, it looks like this:
1 2 3 4 5 6 7 8 9 10 11 | function generateSlug((HasTitle&HasId)|null $post) { if ($post === null) { return ''; } return strtolower($post->getTitle()) . $post->getId(); } |
In this case, (HasTitle & HasId) | null
is of type DNF.
Constants in traits rfc
Now you can use constants in traits:
1 2 3 4 5 6 7 8 9 10 | trait Foo { public const CONSTANT = 1; public function bar(): int { return self::CONSTANT; } } |
You won’t be able to access the constant through the name of the trait, from outside the trait, or from within it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | trait Foo { public const CONSTANT = 1; public function bar(): int { // không thể truy cập từ bên trong! return Foo::CONSTANT; } } // không thể truy cập từ bên ngoài! Foo::CONSTANT; |
However, you can access the constant through the class using trait, provided it’s public:
1 2 3 4 5 6 7 | class MyClass { use Foo; } MyClass::CONSTANT; // 1 |
Redact parameters in back traces rfc
When code running in production often has errors, we can use tracking services to detect this and send them to devs to fix. Usually when an error occurs, there will be stack traces to be able to detect the error, but it also comes with sensitive information such as environment variables, passwords or usernames.
PHP 8.2 allows you to mark such ” sensitive parameters ” with an attribute, so you don’t need to worry about them being listed in stack traces when something goes wrong. Here’s an example from the RFC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function login( string $user, #[SensitiveParameter] string $password <- param này được đánh dấu là param nhạy cảm ) { // … throw new Exception('Error'); } // khi gọi hàm login và có lỗi login('root', 'root'); Fatal error: Uncaught Exception: Error in login.php:8 Stack trace: #0 login.php(11): login('root', Object(SensitiveParameterValue)) #1 {main} thrown in login.php on line 8 |
Fetch properties of enums in const expressions – Get the value of enum in constant expression rfc
1 2 3 4 5 6 7 8 | enum A: string { case B = 'B'; // có thể lấy giá trị B const C = [self::B->value => self::B]; } |
Don’t use string interpolation ${} rfc
PHP has several ways to embed variables in strings. This RFC does not accept two ways of doing so, as they are rarely used and often lead to confusion:
1 2 3 4 5 6 7 | "Hello ${world}"; Deprecated: Using ${} in strings is deprecated "Hello ${(world)}"; Deprecated: Using ${} (variable variables) in strings is deprecated |
Just to be clear: two common ways of string interpolation still work:
1 2 3 | "Hello {$world}"; "Hello $world"; |
Don’t use utf8_encode()
and utf8_decode()
rfc RFC suggests using mb_convert_encoding()
instead
strtolower()
and strtoupper()
no longer support locale characters eg umlaut-a (ä) if you want to help use mb_strtolower()
See the beautiful version at: https://chungnguyen.xyz/posts/what-s-new-in-php-8-2