Công nghệ

Có gì mới trong PHP 8.2

PHP 8.2 được phát hành vào ngày 8 tháng 12 năm 2022. Trong bài viết này, chúng ta sẽ tìm hiểu những tính năng, cải tiến về hiệu suất, thay đổi, và không dùng nữa trong lần phát hành này nhé.

Readonly classes – Lớp chỉ đọc rfc

Ở phiên bản php 8.1 chúng ta có Readonly properties ở phiên bản 8.2 thêm cú pháp để làm cho tất cả các thuộc tính của class chỉ được đọc cùng một lúc.

Thuộc tính chỉ đọc đã được giới thiệu trong PHP 8.1 . RFC này được xây dựng dựa trên chúng và thêm cú pháp để làm cho tất cả các thuộc tính của class chỉ được đọc cùng một lúc.

 # PHP 8.1
    class Post
    {
        public function __construct(
            public readonly string $title, 
            public readonly Author $author,
            public readonly string $body,
            public readonly DateTime $publishedAt,
        ) {}
    }

Bây giờ bạn có thể viết như này:

# PHP 8.2
    readonly class Post
    {
        public function __construct(
            public string $title, 
            public Author $author,
            public string $body,
            public DateTime $publishedAt,
        ) {}
    }

Về mặt chức năng, việc tạo một lớp chỉ đọc hoàn toàn giống với việc tạo mọi thuộc tính ở chế độ chỉ đọcm nhưng nó cũng sẽ ngăn các thuộc tính động được thêm vào một lớp:

    $post = new Post(/* … */);
    
    $post->unknown = 'wrong';
    
    // Sẽ báo lỗi: Uncaught Error: Cannot create dynamic property Post::$unknown

Lưu ý rằng bạn chỉ có thể mở rộng từ các readonly classes  nếu lớp con cũng là readonly class.

New random extension – Phần mở rộng random mới rfc

PHP 8.2 đã thêm vào một trình tạo số ngẫu nhiên mới để giải quyết nhiều vấn đề có trong phiên bản trước. Đặc điểm của trình này là hoạt động hiệu quả hơn, an toàn hơn, dễ bảo trì hơn, và không phụ thuộc vào trạng thái toàn cục. Điều này giúp loại bỏ một loạt các lỗi khó phát hiện khi sử dụng các hàm ngẫu nhiên của PHP.

Có một lớp mới được gọi là Randomizer, chấp nhận một randomizer engine.

$rng = $is_production
    ? new Random\Engine\Secure()
    : new Random\Engine\Mt19937(1234);
 
$randomizer = new Random\Randomizer($rng);
$randomizer->shuffleString('foobar');

nulltrue, and false as standalone types rfc

PHP 8.2 đã bổ sung ba kiểu mới là null, true và false, có thể coi chúng là các kiểu hợp lệ. Một ứng dụng phổ biến của chúng là trong các hàm tích hợp sẵn của PHP, nơi mà false thường được sử dụng làm kiểu trả về khi có lỗi. Ví dụ, trong hàm file_get_contents:

file_get_contents(<em>/* … */</em>): string|false

Trước PHP 8.2, bạn đã có thể sử dụng falsecùng với các loại khác dưới dạng kết hợp, nhưng bây giờ nó cũng có thể được sử dụng như một loại độc lập:

    function alwaysFalse(): false
    {
        return false;
    }
    
    // tương tự với null và true

Disjunctive Normal Form Types – DNF Types rfc

Các loại DNF (Disjunctive Normal Form) cho phép chúng ta kết hợp các kiểu hợp (union – |) và giao (intersection – &) theo một quy tắc nghiêm ngặt: các kiểu giao phải được nhóm với dấu ngoặc. Trong thực tế, điều này có vẻ như sau:

function generateSlug((HasTitle&HasId)|null $post) 
{
    if ($post === null) {
        return '';
    }

    return 
        strtolower($post->getTitle()) 
        . $post->getId();
}

Trong trường hợp này là loại DNF.(HasTitle&HasId)|null

Constants in traits rfc

Bây giờ bạn có thể sử dụng hằng số trong các trait:

trait Foo 
{
    public const CONSTANT = 1;
 
    public function bar(): int 
    {
        return self::CONSTANT;
    }
}

Bạn sẽ không thể truy cập hằng số thông qua tên của trait, từ bên ngoài trait hoặc từ bên trong nó.

trait Foo 
{
    public const CONSTANT = 1;
 
    public function bar(): int 
    {
        return Foo::CONSTANT;
    }
}

Foo::CONSTANT;

Tuy nhiên, bạn có thể truy cập hằng số thông qua class sử dụng trait, với điều kiện là nó công khai:

class MyClass
{
    use Foo;
}

MyClass::CONSTANT; // 1

Redact parameters in back traces rfc

Khi code chạy trên môi trường sản xuất, lỗi thường xuyên xảy ra và để phát hiện và giải quyết chúng, chúng ta thường sử dụng một số dịch vụ để theo dõi. Những dịch vụ này giúp chúng ta bắt kịp các lỗi và gửi chúng đến đội phát triển để khắc phục. Thông thường, khi có lỗi, các stack trace sẽ được cung cấp để giúp xác định nguyên nhân của sự cố. Tuy nhiên, cần lưu ý rằng stack trace cũng chứa thông tin nhạy cảm như biến môi trường, mật khẩu, hoặc tên người dùng.


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

Tìm nạp thuộc tính của enum trong biểu thức const rfc

RFC (Request for Comments) này đề xuất cho phép sử dụng -> hoặc ?-> để truy cập và tìm nạp các thuộc tính của enum trong các biểu thức không đổi. Sự thay đổi này được đề xuất để cho phép tìm nạp các thuộc tính theo tên và giá trị trong những ngữ cảnh không cho phép đối tượng enum, như trong trường hợp sử dụng khóa mảng.

Điều đó có nghĩa là đoạn mã sau hiện hợp lệ:

    enum A: string 
    {
        case B = 'B';
    
        // có thể lấy giá trị B    
        const C = [self::B->value => self::B];
    }


Thay đổi kiểu trả về cho DateTime

Trước đây, các phương pháp này trông như thế này:

DateTime::createFromImmutable(): DateTime
DateTimeImmutable::createFromMutable(): DateTimeImmutable

Trong PHP 8.2, các chữ ký phương thức đó được thay đổi như sau:

DateTime::createFromImmutable(): static
DateTimeImmutable::createFromMutable(): static

Thay đổi này mang ý nghĩa quan trọng vì nó cải thiện khả năng hiểu biết tĩnh cho các lớp mở rộng từ DateTime và DateTimeImmutable. Tuy nhiên, từ góc độ kỹ thuật, đây là một thay đổi đột phá có thể ảnh hưởng đến việc triển khai tùy chỉnh cho lớp mở rộng từ một trong hai lớp nêu trên.

Không dùng utf8_encode() và utf8_decode()

Trong PHP 8.2, việc sử dụng một trong hai utf8_encode()hoặc utf8_decode()sẽ kích hoạt các thông báo ngừng sử dụng này:

utf8_encode($string);
// Deprecated: Function utf8_encode() is deprecated

utf8_decode($string)
// Deprecated: Function utf8_decode() is deprecated

Thay thế:

//utf8_encode($string);
mb_convert_encoding($string, 'UTF-8');

//utf8_decode($string)
mb_convert_encoding($string, 'ISO-8859-1', 'UTF-8');

Không dùng ${} nội suy chuỗi

"Hello ${world}";
//Deprecated: Using ${} in strings is deprecated

 
"Hello ${(world)}";
//Deprecated: Using ${} (variable variables) in strings is deprecated

Nói rõ hơn: hai cách nội suy chuỗi phổ biến vẫn hoạt động:

"Hello {$world}";
"Hello $world";

Bài viết liên quan

Chat