Quay lại

Các tính năng mới tuyệt vời của PHP 8.1 Chuyên mục PHP và Laravel    2023-05-11    575 Lượt xem    90 Lượt thích    comment-3 Created with Sketch Beta. 0 Bình luận

Các tính năng mới tuyệt vời của PHP 8.1

Phiên bản lớn mới nhất của PHP đã được phát hành cách đây. Nó mang lại một số tính năng tuyệt vời giúp bạn dễ dàng hơn và code của bạn dễ đọc hơn. Tôi đã sử dụng nó trong phát triển và nhiều người khác cũng vậy, vì vậy bây giờ là thời điểm hoàn hảo để xem qua tất cả các tính năng mới của PHP 8.1.

Bài viết này sẽ cho bạn thấy những tính năng mới nhất và tuyệt vời nhất của PHP 8.1, đi kèm với các khối mã đơn giản.

Hỗ trợ riêng cho enums

Đây chắc chắn là tính năng lớn nhất của PHP 8.1: enums. Tôi nghĩ rằng nhiều người sẽ yêu thích chúng, mặc dù nếu bạn chưa bao giờ sử dụng một số class giống như enum, bạn có thể cần xem giá trị của chúng trước khi yêu thích nó.

Tóm lại, enums là gì?

Bạn đã bao giờ gặp tình huống mà một thứ gì đó (chẳng hạn như bản ghi cơ sở dữ liệu) có thể có nhiều trạng thái chưa? Và bạn đã bao giờ muốn 'programmatically enforce’ that state' (Thực thi chương trình theo trạng thái )? 

Hãy tưởng tượng một hóa đơn: nó có thể có các trạng thái như  draft, pending, paid and expired và chúng ta đang lưu trữ các trạng thái đó trong cơ sở dữ liệu dưới dạng chuỗi. Nhưng làm thế nào để chúng ta thực thi trạng thái này, để nó chỉ có thể có một giá trị từ một tập hợp các giá trị nhất định?

Mọi người sẽ đồng ý rằng status như "exploded" không có ý nghĩa đối với hóa đơn, vì vậy câu hỏi đặt ra là: chúng ta có thể đảm bảo rằng chúng ta chỉ có trạng thái hợp lệ không?

Tất nhiên bạn có thể viết bằng các câu lệnh if-else và các điều kiện tương tự khác, nhưng điều đó không lý tưởng lắm. Đặc biệt khi một dự án trở nên lớn hơn và nhiều người cùng làm việc với nó, điều này thật không tốt chút nào.

Enums là giải pháp cho vấn đề quản lý trạng thái ở trên. Trên thực tế, bản thân một enum là một trạng thái nhất định. Nó hoạt động như thế này:

  1. Enum là một lớp PHP, ngoại trừ việc chúng được định nghĩa bằng từ khóa enum thay vì từ khóa class.
  2. Trong enum, bạn có thể xác định tất cả các giá trị được phép (như draft, pending, paid, v.v.).
  3. Đối với mỗi giá trị đó, bạn xác định một chuỗi, có thể được sử dụng để lưu trữ trạng thái trong cơ sở dữ liệu.
  4. Bất cứ khi nào bạn truy xuất một bản ghi cơ sở dữ liệu, bạn truyền giá trị chuỗi tới đúng đối tượng enum.
  5. Bây giờ bạn hoàn toàn chắc chắn rằng không có giá trị kỳ lạ nào có thể được sử dụng cho một trạng thái (nó sẽ đưa ra một ngoại lệ). Và bạn có thể làm những việc như: if ($state === InvoiceStatus::paid)

Cách sử dụng enum

Bây giờ chúng ta đã biết lý thuyết về enums trong PHP, vậy chúng ta sử dụng enums như thế nào? Xác định một enum rất dễ dàng:

<?php
 
namespace App\Enums;
 
enum InvoiceStatus: string {
    case draft = ‘draft’;
    case pending = ‘pending’;
    case paid = ‘paid’;
    case expired = ‘expired’;
}

Bạn có thể sử dụng chúng như thế này:

use App\Enums\InvoiceStatus;
 
$stateAsString = 'pending';
 
$state = InvoiceStatus::from($stateAsString); // Returns exception if fails
// Or: $state = InvoiceStatus::tryFrom($stateAsString); // Returns null if fails

Đơn giản, phải không? Bạn cũng có thể thêm các phương thức, triển khai interface, sử dụng các trait và nhiều thứ khác. 

Readonly properties

Một vấn đề quan trọng khác (nhưng kém quan trọng hơn một chút so với enums) là giới thiệu các thuộc tính chỉ Readonly. Như tên gợi ý, bây giờ bạn có thể đặt các thuộc tính trên một class thành chỉ có thể readonly. Điều đó có nghĩa là chúng không thể thay đổi sau khi chúng được thiết lập lần đầu tiên.

Nếu trước đây bạn muốn đạt được hiệu ứng chỉ đọc đó, bạn phải chọn một trong các tùy chọn sau:

  1. Đặt thuộc tính thành công khai và đồng ý rằng không ai có thể viết thư cho nó.
  2. Đặt thuộc tính thành protected hoặc private và thêm phương thức getter đặc biệt vào class (như getName(), getTitle(), v.v.)

Phương pháp đầu tiên không an toàn 100% và phương pháp thứ hai rất nhàm chán. Bây giờ hãy kiểm tra ví dụ PHP8.1 sau

<?php
 
namespace App\DataTransferObjects;
 
use App\Enums\PaymentStatus;
 
class PaymentData {
    public function __construct(
        public readonly string $uuid,
        public readonly int $amount,
        public readonly PaymentStatus $status, /* See this little enum? :-) */
    ) {}
}

Bây giờ bạn chắc chắn 100% rằng các thuộc tính có thể được đặt một lần và chỉ một lần và không bao giờ thay đổi sau đó.

Array unpacking với string keys

Array unpacking là một cú pháp rất rõ ràng và nice syntax (available kể từ PHP 7.4), nhưng thật không may, bạn vẫn cần phải dùng Array_merge() cũ cho các string key. Không còn nữa!

<?php
 
$author = [
    'name' => 'John',
    'age' => '25',
];
 
$job = [
    'title' => 'Developer',
];
 
$authorInfo = [
    ...$author,
    ...$job,
];
 
// => [
//    'name' => 'John',
//    'age' => '25',
//    'title' => 'Developer',
//]

Sử dụng `new Class()` trong constructors/initializers

Bạn hẳn đã biết rằng chúng ta có thể gán giá trị mặc định cho tham số trong functioncontractor. Bây giờ, chúng ta cũng có thể tự động một instance of a class mà không cần phải truyền nó vào hàm nữa!

<?php
 
use App\Enums\PaymentStatus;
use App\DataTransferObjects\Subscription;
 
class PaymentData {
    public function __construct(
        public readonly string $uuid,
        public readonly int $amount,
        public readonly PaymentStatus $status,
        public readonly Subscription = new Subscription(),
    ) {}
 
    public function newSubscription(
        $subscription = new Subscription(),
    ) {}
}

Cách kiểm tra xem một mảng PHP có phải là một danh sách không?

Bạn đã bao giờ cần kiểm tra xem một mảng có phải là một danh sách thuần túy không (với các khóa chỉ đi từ 0, 1, 2, v.v.)?  hàm array_is_list($array) sẽ hỗ trợ bạn!

<?php
 
$array = [
    'Full-stack developer',
    'Front-end developer',
    'Back-end developer',
];
 
array_is_list($array);
// true
 
$array = [
    'a' => 'Full-stack developer',
    'b' => 'Front-end developer',
    'c' => 'Back-end developer',
];
 
array_is_list($array);
// false

Tạo callables trực tiếp từ một function

Giờ đây, bạn có thể dễ dàng tạo một lệnh callable/callback derectly từ một function. Nó là khá tuyệt vời và rất gọn gàng.

<?php
 
use App\Models\User;
use App\DataTransferObjects\PaymentData;
 
function createPayment(int $amount, User $user): PaymentData {
  // Do something
}
 
$createPayment = createPayment(...);
 
$paymentData = $createPayment(amount: 100, user: User::first());

Intersection types

Tính năng cuối cùng của PHP 8.1 nghe có vẻ hơi mơ hồ, nhưng một ví dụ sẽ nhanh chóng làm sáng tỏ mọi thứ. Bạn đã từng viết một hàm chấp nhận một tham số như bên dưới chưa?

public function createPayments(array|Collection $payments) {
  //
}

Như bạn thấy, tham số $payments chỉ có thể là một mảng hoặc một Bộ sưu tập(collection) chứ không thể là một chuỗi hoặc bất kỳ thứ gì khác. Nó phải là cái này hay cái kia. Bây giờ bạn cũng có thể xác định tham số nên có hay có cả hai loại.

Nếu bạn đang thắc mắc, làm thế nào một tham số có thể có hai loại? Ý tôi là, bạn không bao giờ có thể có một chuỗi và một mảng cùng một lúc. Cách ở đây là typehint interfacesn, nghĩa là bây giờ bạn có thể chỉ định rằng bạn muốn nhận một đối tượng thực hiện hai interface:

function generatePaymentLink(Billable&Subscriber $user) {
  //
}

Bây giờ, tham số $user phải là một đối tượng (object) implement cả interface Billable và là Subscriber.

Tổng kết

Như bạn đã thấy, PHP 8.1 mang đến một số tính năng mới thú vị và những cải tiến. Đúng vậy, nhiều thứ đã có thể thực hiện được trước đây, nhưng các tính năng mới cho phép bạn viết mã rõ ràng hơn nhiều. (Đó là lý do tại sao tôi rất thích quảng cáo thuộc tính PHP 8.1, bởi vì nó làm sạch mã của bạn rất nhiều.)

Giờ đây, bạn có thể thay thế tất cả các getter của mình bằng các thuộc tính chỉ readonly, sử dụng enums nguyên bản thay vì package, tùy chỉnh hàm PHP của bạn để xác định xem một mảng có phải là danh sách hay không, v.v.

Ngoài ra còn có một tính năng cuối cùng khác rất hay được đề cập, nhưng một tính năng mà bạn có thể sẽ không sử dụng thường xuyên. Nó cho phép bạn thực hiện nhiều quyền kiểm soát hơn đối với luồng chương trình và bạn có thể thực hiện đồng thời một số việc nhất định. 

Cảm ơn vì đã đọc bài viết này.

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday