Được phát hành vào ngày 25 tháng 11 năm 2021, PHP 8.1 cuối cùng cũng có mặt ở đây với một số tính năng thú vị.

Trong bài viết này, chúng tôi sẽ trình bày chi tiết những điểm mới trong PHP 8.1. Từ các tính năng mới và cải tiến hiệu suất cho đến những thay đổi đáng kể và không còn được dùng nữa, chúng tôi sẽ đi sâu vào tất cả.

Kiên nhẫn ngồi chờ!

Table of Contents

Các tính năng mới trong PHP 8.1

Hãy bắt đầu bằng cách bao gồm tất cả các tính năng mới trong PHP 8.1. Đó là một danh sách khá.

Các loại giao điểm thuần túy

PHP 8.1 hỗ trợ thêm cho các kiểu giao nhau. Nó tương tự như các kiểu union được giới thiệu trong PHP 8.0, nhưng mục đích sử dụng của chúng thì hoàn toàn ngược lại.

Để hiểu cách sử dụng của nó tốt hơn, hãy làm mới cách khai báo kiểu hoạt động trong PHP.

Về cơ bản, bạn có thể thêm khai báo kiểu vào đối số hàm, giá trị trả về và thuộc tính lớp. Phép gán này được gọi là gợi ý kiểu và đảm bảo rằng giá trị thuộc kiểu chính xác tại thời điểm gọi. Nếu không, nó sẽ tạo ra một TypeError ngay lập tức. Đổi lại, điều này giúp bạn gỡ lỗi mã tốt hơn.

Tuy nhiên, khai báo một kiểu duy nhất có những hạn chế của nó. Các kiểu liên minh giúp bạn khắc phục điều đó bằng cách cho phép bạn khai báo một giá trị với nhiều kiểu và đầu vào phải đáp ứng ít nhất một trong các kiểu đã khai báo.

Mặt khác, RFC mô tả các kiểu giao cắt như sau:

“Kiểu giao nhau” yêu cầu một giá trị để đáp ứng nhiều ràng buộc kiểu thay vì một giá trị duy nhất.

… Kiểu giao nhau thuần túy được chỉ định bằng cú pháp T1 & T2 &… và có thể được sử dụng ở tất cả các vị trí mà kiểu hiện đang được chấp nhận…

Lưu ý việc sử dụng toán tử & (AND) để khai báo các kiểu giao nhau. Ngược lại, chúng tôi sử dụng dấu | (HOẶC) toán tử để khai báo các kiểu liên hợp.

Việc sử dụng hầu hết các kiểu tiêu chuẩn trong kiểu giao nhau sẽ dẫn đến kiểu không bao giờ có thể được thực hiện (ví dụ: số nguyên và chuỗi). Do đó, các kiểu giao nhau chỉ có thể bao gồm các kiểu lớp (tức là các giao diện và tên lớp).

Đây là mã ví dụ về cách bạn có thể sử dụng các loại giao lộ:

class A {  private Traversable&Countable $countableIterator;  public function setIterator(Traversable&Countable $countableIterator): void {    $this->countableIterator = $countableIterator;  }  public function getIterator(): Traversable&Countable {    return $this->countableIterator;  } }

Trong đoạn mã trên, chúng tôi đã xác định biến countableIterator như một giao điểm của hai loại: Có thể duyệt và Có thể đếm được. Trong trường hợp này, hai kiểu được khai báo là giao diện.

Các kiểu giao nhau cũng tuân theo các quy tắc phương sai PHP tiêu chuẩn đã được sử dụng để kiểm tra kiểu và kế thừa. Nhưng có hai quy tắc bổ sung về cách các kiểu giao nhau tương tác với kiểu con. Bạn có thể đọc thêm về quy tắc phương sai của các loại giao lộ trong RFC của nó.

Trong một số ngôn ngữ lập trình, bạn có thể kết hợp Kiểu Liên hợp và Kiểu Giao nhau trong cùng một khai báo. Nhưng PHP 8.1 cấm điều đó. Do đó, cách triển khai của nó được gọi là kiểu giao nhau “thuần túy”. Tuy nhiên, RFC đề cập rằng nó “được để lại như một phạm vi trong tương lai.”

Enums

PHP 8.1 cuối cùng cũng bổ sung hỗ trợ cho enums (còn được gọi là kiểu liệt kê hoặc kiểu liệt kê). Chúng là kiểu dữ liệu do người dùng xác định bao gồm một tập hợp các giá trị có thể có.

Ví dụ enums phổ biến nhất trong các ngôn ngữ lập trình là kiểu boolean , với truefalse là hai giá trị có thể. Nó phổ biến đến mức nó được đưa vào nhiều ngôn ngữ lập trình hiện đại.

Theo RFC, ban đầu, enums trong PHP sẽ bị hạn chế ở “kiểu liệt kê đơn vị”:

Phạm vi của RFC này được giới hạn trong “các phép liệt kê đơn vị”, nghĩa là, các phép liệt kê tự nó là một giá trị, thay vì chỉ đơn giản là một cú pháp ưa thích cho một hằng số nguyên thủy và không bao gồm thông tin liên quan bổ sung. Khả năng này cung cấp hỗ trợ mở rộng đáng kể cho mô hình dữ liệu, định nghĩa kiểu tùy chỉnh và hành vi kiểu đơn nguyên. Enums cho phép kỹ thuật mô hình hóa “làm cho các trạng thái không hợp lệ không thể biểu diễn được”, dẫn đến mã mạnh hơn mà không cần phải kiểm tra toàn diện.

Để đến được giai đoạn này, nhóm PHP đã nghiên cứu nhiều ngôn ngữ đã hỗ trợ phép liệt kê. Cuộc khảo sát của họ cho thấy rằng bạn có thể phân loại liệt kê thành ba nhóm chung: Hằng số ưa thích, Đối tượng ưa thích và Các kiểu dữ liệu đại số (ADT) đầy đủ. Đó là một bài đọc thú vị!

PHP triển khai các enums “Fancy Objects”, với kế hoạch mở rộng nó thành các ADT đầy đủ trong tương lai. Nó được mô hình hóa về mặt khái niệm và ngữ nghĩa dựa trên các kiểu được liệt kê trong Swift, Rust và Kotlin, mặc dù nó không được mô hình hóa trực tiếp trên bất kỳ kiểu nào trong số đó.

RFC sử dụng sự tương tự nổi tiếng của các bộ quần áo trong một bộ bài để giải thích cách hoạt động của nó:

enum Suit { case Hearts; case Diamonds; case Clubs; case Spades; }

Ở đây, enum Suit xác định bốn giá trị có thể có: Hearts , Diamonds , ClubSpades . Bạn có thể truy cập trực tiếp các giá trị này bằng cú pháp: Suit::Hearts , Suit::Diamonds , Suit::ClubsSuit::Spades .

Cách sử dụng này có vẻ quen thuộc, vì enum được xây dựng trên cùng các lớp và đối tượng. Họ cư xử tương tự và có các yêu cầu gần như chính xác. Enums có chung không gian tên như các lớp, giao diện và đặc điểm.

Enums nói trên được gọi là Pure Enums .

Bạn cũng có thể định nghĩa Backed Enums nếu bạn muốn cung cấp một giá trị tương đương vô hướng cho bất kỳ trường hợp nào. Tuy nhiên, enum được hỗ trợ chỉ có thể có một kiểu, int hoặc string (không bao giờ có cả hai).

enum Suit: string { case Hearts = 'H'; case Diamonds = 'D'; case Clubs = 'C'; case Spades = 'S'; }

Hơn nữa, tất cả các trường hợp khác nhau của một enum được hỗ trợ phải có một giá trị duy nhất. Và bạn không bao giờ có thể kết hợp enum nguyên chất và được hỗ trợ.

RFC nghiên cứu sâu hơn về các phương thức enum, phương thức tĩnh, hằng số, biểu thức hằng và hơn thế nữa. Đề cập đến tất cả chúng nằm ngoài phạm vi của bài viết này. Bạn có thể tham khảo tài liệu để làm quen với tất cả các tính tốt của nó.

Loại never trả lại

PHP 8.1 thêm một gợi ý kiểu trả về mới có tên là never . Sẽ rất hữu ích khi sử dụng trong các hàm luôn throw hoặc exit .

Theo RFC, các hàm chuyển hướng URL luôn exit (rõ ràng hoặc ẩn ý) là một ví dụ điển hình cho việc sử dụng nó:

function redirect(string $uri): never {  header('Location: ' . $uri);  exit(); } function redirectToLoginPage(): never {  redirect('/login'); }

Một hàm never khai báo phải thỏa mãn ba điều kiện:

  • Nó không nên có câu lệnh return được xác định rõ ràng.
  • Nó không nên có câu lệnh return được định nghĩa ngầm (ví dụ: câu lệnh if-else ).
  • Nó phải kết thúc việc thực thi bằng một câu lệnh exit (rõ ràng hoặc ngầm định).

Ví dụ về chuyển hướng URL ở trên cho thấy cả cách sử dụng ẩn và rõ ràng của kiểu never return.

Kiểu never return có nhiều điểm tương đồng với kiểu void return. Cả hai đều đảm bảo rằng hàm hoặc phương thức không trả về giá trị. Tuy nhiên, nó khác bằng cách thực thi các quy tắc chặt chẽ hơn. Ví dụ: một hàm void -declared vẫn có thể return mà không có giá trị rõ ràng, nhưng bạn không thể làm điều tương tự với một hàm never -declared.

Theo nguyên tắc chung, hãy void khi bạn mong đợi PHP tiếp tục thực thi sau lệnh gọi hàm. Đi với never khi bạn muốn ngược lại.

Hơn nữa, never được định nghĩa là loại “dưới cùng”. Do đó, bất kỳ phương thức lớp nào được khai báo never có thể “không bao giờ” thay đổi kiểu trả về của nó thành một thứ khác. Tuy nhiên, bạn có thể mở rộng phương thức void -declared bằng phương thức never -declared.

Sợi

Trong lịch sử, mã PHP hầu như luôn là mã đồng bộ. Quá trình thực thi mã tạm dừng cho đến khi kết quả được trả về, ngay cả đối với các hoạt động I / O. Bạn có thể tưởng tượng tại sao quá trình này có thể làm cho việc thực thi mã chậm hơn.

Có nhiều giải pháp của bên thứ ba để khắc phục trở ngại này để cho phép các nhà phát triển viết mã PHP không đồng bộ, đặc biệt là đối với các hoạt động I / O đồng thời. Một số ví dụ phổ biến bao gồm amphp, ReactPHP và Guzzle.

Tuy nhiên, không có cách chuẩn nào để xử lý các trường hợp như vậy trong PHP. Hơn nữa, việc xử lý mã đồng bộ và không đồng bộ trong cùng một ngăn xếp cuộc gọi dẫn đến các vấn đề khác.

Fibers là cách PHP xử lý song song thông qua các luồng ảo (hoặc luồng xanh). Nó tìm cách loại bỏ sự khác biệt giữa mã đồng bộ và không đồng bộ bằng cách cho phép các hàm PHP ngắt mà không ảnh hưởng đến toàn bộ ngăn xếp cuộc gọi.

Đây là những gì RFC hứa hẹn :

  • Thêm hỗ trợ cho Fibers cho PHP.
  • Giới thiệu một lớp Fiber mới và lớp phản xạ tương ứng ReflectionFiber.
  • Thêm các lớp ngoại lệ FiberError và FiberExit để đại diện cho các lỗi.
  • Các sợi cho phép triển khai I / O không chặn trong suốt của các giao diện hiện có (PSR-7, Doctrine ORM, v.v.). Đó là bởi vì đối tượng giữ chỗ (lời hứa) bị loại bỏ. Thay vào đó, các hàm có thể khai báo kiểu kết quả I / O thay vì một đối tượng giữ chỗ không thể chỉ định kiểu phân giải vì PHP không hỗ trợ generics.

Bạn có thể sử dụng Fibers để phát triển các hàm PHP toàn ngăn xếp, có thể ngắt quãng, sau đó bạn có thể sử dụng chúng để triển khai đa nhiệm hợp tác trong PHP. Khi Fibers tạm dừng toàn bộ ngăn xếp thực thi, bạn có thể yên tâm khi biết rằng nó sẽ không gây hại cho phần còn lại của mã của bạn.

Chart illustrating PHP code execution flow with Fibers.
Biểu đồ minh họa luồng thực thi mã PHP với Fibers (Nguồn: PHP.net).

Để minh họa việc sử dụng Fibers, RFC của nó sử dụng ví dụ đơn giản sau:

$fiber = new Fiber(function (): void {  $value = Fiber::suspend('fiber');  echo "Value used to resume fiber: ", $value, "n"; }); $value = $fiber->start(); echo "Value from fiber suspending: ", $value, "n"; $fiber->resume('test');

Bạn đang tạo một “sợi” trong đoạn mã trên và ngay lập tức đình chỉ nó bằng fiber chuỗi. Câu lệnh echo đóng vai trò như một tín hiệu trực quan cho việc nối lại sợi quang.

Bạn có thể truy xuất giá trị chuỗi này từ cuộc gọi đến $fiber->start() .

Sau đó, bạn tiếp tục cáp quang với chuỗi “test”, được trả về từ lệnh gọi đến Fiber::suspend() . Việc thực thi mã đầy đủ dẫn đến kết quả đầu ra có nội dung:

Value from fiber suspending: fiber Value used to resume fiber: test

Đó là ví dụ trong sách giáo khoa về PHP Fibers tại nơi làm việc. Đây là một ví dụ khác của Fibers về việc thực hiện bảy yêu cầu GET không đồng bộ.

Với tất cả những gì đã được nói và làm, hầu hết các nhà phát triển PHP sẽ không bao giờ giao dịch trực tiếp với Fibers. Và RFC thậm chí còn gợi ý như vậy:

Sợi là một tính năng nâng cao mà hầu hết người dùng sẽ không sử dụng trực tiếp. Tính năng này chủ yếu nhắm mục tiêu đến các tác giả thư viện và khuôn khổ để cung cấp một vòng lặp sự kiện và một API lập trình không đồng bộ. Fibers cho phép tích hợp thực thi mã không đồng bộ một cách liền mạch vào mã đồng bộ tại bất kỳ điểm nào mà không cần sửa đổi ngăn xếp lệnh gọi ứng dụng hoặc thêm mã bản ghi sẵn.

API Fibre dự kiến sẽ không được sử dụng trực tiếp trong mã cấp ứng dụng. Fibers cung cấp một API điều khiển luồng cấp cơ bản, cấp thấp để tạo ra các trừu tượng cấp cao hơn, sau đó được sử dụng trong mã ứng dụng.

Xem xét các lợi ích về hiệu suất của nó, bạn có thể mong đợi các thư viện và khuôn khổ PHP tận dụng lợi thế của tính năng mới này. Sẽ rất thú vị khi xem cách họ triển khai Fibers trong hệ sinh thái của họ.

Thuộc tính readonly mới

PHP 8.1 bổ sung hỗ trợ cho các thuộc tính readonly . Chúng chỉ có thể được khởi tạo một lần từ phạm vi mà chúng được khai báo. Sau khi khởi tạo, bạn không thể sửa đổi giá trị của chúng. Làm như vậy sẽ xuất hiện một ngoại lệ Lỗi .

RFC của nó đọc:

Thuộc tính chỉ đọc chỉ có thể được khởi tạo một lần và chỉ từ phạm vi mà nó đã được khai báo. Bất kỳ sự chuyển nhượng hoặc sửa đổi nào khác đối với thuộc tính sẽ dẫn đến một ngoại lệ Lỗi.

Dưới đây là một ví dụ về cách bạn có thể sử dụng nó:

class Test {  public readonly string $kinsta;  public function __construct(string $kinsta) {    // Legal initialization.    $this->kinsta = $kinsta;  } }

Sau khi khởi tạo, không có quay lại. Việc đưa tính năng này vào PHP làm giảm đáng kể mã soạn sẵn thường được sử dụng để kích hoạt chức năng này.

Thuộc tính readonly cung cấp một đảm bảo tính bất biến mạnh mẽ, cả bên trong và bên ngoài lớp. Không quan trọng mã chạy ở giữa. Việc gọi thuộc tính readonly sẽ luôn trả về cùng một giá trị.

Tuy nhiên, việc sử dụng thuộc tính readonly có thể không lý tưởng trong các trường hợp sử dụng cụ thể. Ví dụ: bạn chỉ có thể sử dụng chúng cùng với một thuộc tính đã định kiểu vì các khai báo không có kiểu sẽ hoàn toàn là null và không thể readonly được.

Hơn nữa, việc đặt thuộc tính readonly không làm cho các đối tượng trở nên bất biến. Thuộc tính readonly sẽ giữ cùng một đối tượng, nhưng bản thân đối tượng đó có thể thay đổi.

Một vấn đề nhỏ khác với thuộc tính này là bạn không thể sao chép nó. Đã có một giải pháp cho trường hợp sử dụng cụ thể này. Xem xét nó nếu cần thiết.

Xác định các hằng số lớp final

Kể từ PHP 8.0, bạn có thể ghi đè các hằng số lớp bằng các lớp con của nó. Đó là do cách kế thừa được thực hiện trong PHP.

Dưới đây là một ví dụ về cách bạn có thể ghi đè giá trị của một hằng số đã khai báo trước đó:

class Moo {  public const M = "moo"; } class Meow extends Moo {  public const M = "meow"; }

Bây giờ, nếu lũ bò muốn chặt chẽ hơn với cách chúng cư xử với mèo (ít nhất là với hằng số), chúng có thể làm như vậy với công cụ sửa đổi final mới của PHP 8.1.

Khi bạn đã khai báo một hằng số là final , điều đó có nghĩa là.

class Moo {  final public const M = "moo"; } class Meow extends Moo {  public const M = "meow"; } // Fatal error: Meow::M cannot override final constant Moo::M

Bạn có thể đọc thêm về nó trong hằng số lớp cuối cùng PHP RFC.

Các hàm fsync()fdatasync() mới

PHP 8.1 bổ sung thêm hai hàm hệ thống tệp mới có tên fsync()fdatasync() . Chúng sẽ có vẻ quen thuộc đối với những người đã từng sử dụng các chức năng cùng tên của Linux. Đó là bởi vì chúng có liên quan, chỉ được triển khai cho PHP.

Trên thực tế, việc bổ sung này đã quá hạn từ lâu. PHP là một trong số ít các ngôn ngữ lập trình lớn vẫn chưa triển khai fsync () và fdatasync () – tức là cho đến PHP 8.1.

Hàm fsync() tương tự như hàm fflush() hiện có của PHP, nhưng nó khác đáng kể theo một cách. Trong khi fflush() chuyển các bộ đệm bên trong của ứng dụng sang hệ điều hành, thì fsync() tiến thêm một bước nữa và đảm bảo rằng các bộ đệm bên trong được chuyển vào bộ nhớ vật lý. Điều đó đảm bảo quá trình ghi hoàn chỉnh và liên tục để bạn có thể truy xuất dữ liệu ngay cả sau khi ứng dụng hoặc hệ thống gặp sự cố.

Đây là một ví dụ về cách bạn có thể sử dụng nó.

$doc = 'kinsta.txt'; $kin = fopen($doc, 'ki'); fwrite($kin, 'doc info'); fwrite($kin, "rn"); fwrite($kin, 'more info'); fsync($kin); fclose($kin);

Việc thêm lệnh gọi fsync() vào cuối đảm bảo rằng mọi dữ liệu được giữ trong PHP hoặc bộ đệm bên trong của hệ điều hành sẽ được ghi vào bộ nhớ. Tất cả các quá trình thực thi mã khác đều bị chặn cho đến lúc đó.

Hàm liên quan của nó là fdatasync() . Sử dụng nó để đồng bộ hóa dữ liệu nhưng không nhất thiết phải là siêu dữ liệu. Đối với dữ liệu có siêu dữ liệu không cần thiết, lệnh gọi hàm này giúp quá trình ghi nhanh hơn một chút.

Tuy nhiên, bạn cần lưu ý rằng PHP 8.1 chưa hỗ trợ đầy đủ fdatasync() trên Windows. Nó chỉ hoạt động như một bí danh của fsync() . Trên POSIX, fdatasync() được triển khai đúng cách.

array_is_list() mới

Mảng PHP có thể chứa cả khóa số nguyên và chuỗi. Điều đó có nghĩa là bạn có thể sử dụng chúng cho một số thứ, bao gồm danh sách, bảng băm, từ điển, bộ sưu tập, ngăn xếp, hàng đợi, v.v. Bạn thậm chí có thể có các mảng trong mảng, tạo ra các mảng đa chiều.

Bạn có thể kiểm tra một cách hiệu quả liệu một mục cụ thể có phải là một mảng hay không, nhưng không dễ dàng để kiểm tra xem nó có bất kỳ phần bù mảng nào bị thiếu, khóa không theo thứ tự, v.v. Nói tóm lại, bạn không thể nhanh chóng xác minh xem một mảng có phải là một danh sách hay không.

Hàm array_is_list () kiểm tra xem các khóa của mảng có theo thứ tự tuần tự bắt đầu từ 0 và không có khoảng trống hay không. Nếu tất cả các điều kiện được đáp ứng, nó sẽ trả về true . Theo mặc định, nó cũng trả về true cho các mảng trống.

Dưới đây là một số ví dụ về việc sử dụng nó với cả điều kiện truefalse được đáp ứng:

// true array_is_list() examples array_is_list([]); // true array_is_list([1, 2, 3]); // true array_is_list(['cats', 2, 3]); // true array_is_list(['cats', 'dogs']); // true array_is_list([0 => 'cats', 'dogs']); // true array_is_list([0 => 'cats', 1 => 'dogs']); // true // false array_is_list() examples array_is_list([1 => 'cats', 'dogs']); // as first key isn't 0 array_is_list([1 => 'cats', 0 => 'dogs']); // keys are out of order array_is_list([0 => 'cats', 'bark' => 'dogs']); // non-integer keys array_is_list([0 => 'cats', 2 => 'dogs']); // gap in between keys

Một danh sách mảng PHP với các khóa không theo thứ tự là một nguồn lỗi tiềm ẩn. Sử dụng hàm này để thực thi tuân thủ nghiêm ngặt các yêu cầu của danh sách trước khi tiếp tục thực thi mã là một bổ sung tuyệt vời cho PHP.

Chức năng Sodium XChaCha20 mới

Sodium là một thư viện mật mã hiện đại, dễ sử dụng để mã hóa, giải mã, băm mật khẩu, chữ ký và hơn thế nữa. Gói libsodium PECL thêm một trình bao bọc cho Sodium để các nhà phát triển PHP có thể sử dụng nó.

Ngay cả các công ty công nghệ hàng đầu như Facebook, Discord, Malwarebytes và Valve cũng sử dụng libsodium để bảo mật người dùng của họ bằng các kết nối nhanh chóng và an toàn.

libsodium hỗ trợ thuật toán mã hóa XChaCha20 để mã hóa và giải mã dữ liệu, đặc biệt là đối với mã hóa luồng. Tương tự như vậy, phần mở rộng PECL libsodium đã hỗ trợ XChaCha20, nhưng chỉ với mã xác thực tin nhắn Poly1305.

Nhiều ứng dụng PHP sử dụng XChaCha20 trực tiếp để mã hóa luồng. Để làm cho mọi thứ dễ dàng hơn, bắt đầu với PHP 8.1, bạn sẽ có ba chức năng mới để mã hóa hoặc giải mã dữ liệu với XChaCha20 mà không cần xác thực. Chế độ này được gọi là “chế độ tách rời”.

Các chức năng XChaCha20 mới được giới thiệu là:

  • sodium_crypto_stream_xchacha20_keygen : Trả về một khóa ngẫu nhiên an toàn để sử dụng với sodium_crypto_stream_xchacha20.
  • sodium_crypto_stream_xchacha20 : Mở rộng khóa và nonce thành một dòng khóa gồm các byte giả ngẫu nhiên.
  • sodium_crypto_stream_xchacha20_xor : Mã hóa tin nhắn bằng cách sử dụng nonce và khóa bí mật (không xác thực).

Ngoài ra, có hai hằng số PHP mới được định nghĩa trong không gian tên chung:

  • SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES (được chỉ định 32 )
  • SODIUM_CRYPTO_STREAM_XCHACHA20_NONCEBYTES (được chỉ định 24 )

Tuy nhiên, hãy sử dụng nó một cách thận trọng. Vì nó không có xác thực, hoạt động giải mã dễ bị tấn công bản mã phổ biến.

Bạn có thể đọc thêm về cách sử dụng và yêu cầu của nó trên trang GitHub.

Lớp IntlDatePatternGenerator mới

Thư viện ICU cơ bản của PHP hỗ trợ việc tạo các định dạng ngày và giờ được bản địa hóa, nhưng nó không hoàn toàn có thể tùy chỉnh được.

Ví dụ: nếu bạn muốn tạo dữ liệu theo ngôn ngữ cụ thể và định dạng thời gian cho đến PHP 8.0, bạn có thể sử dụng hằng số IntlDateFormatter được xác định trước để thực hiện theo 6 cách:

  • IntlDateFormatter::LONG : Dài hơn, chẳng hạn như ngày 10 tháng 11 năm 2017 hoặc 11:22:33 chiều
  • IntlDateFormatter::MEDIUM : Ngắn hơn một chút, chẳng hạn như ngày 10 tháng 11 năm 2017
  • IntlDateFormatter::SHORT : Chỉ là số, chẳng hạn như 10/11/17 hoặc 11:22 chiều

Mỗi biến thể này cũng có các biến thể RELATIVE_ của riêng nó, đặt định dạng ngày trong một phạm vi giới hạn trước hoặc sau ngày hiện tại. Trong PHP, các giá trị là ngày hôm qua , hôm nayngày mai .

Giả sử bạn muốn sử dụng phiên bản dài cho năm và phiên bản ngắn cho tháng, chẳng hạn như 10/11/2017 . Đối với PHP 8.0, bạn không thể.

Trong PHP 8.1+, bạn có thể chỉ định định dạng nào sẽ sử dụng cho ngày, tháng và giờ với lớp IntlDatePatternGenerator mới. Bạn có thể để lại thứ tự chính xác của các thành phần này cho bộ định dạng.

Bạn nên lưu ý rằng mặc dù lớp này chỉ có từ Date trong đó, nhưng nó nhất quán với DateTimePatternGenerator của ICU. Điều đó có nghĩa là bạn cũng có thể sử dụng nó để tạo các định dạng thời gian linh hoạt. Để đơn giản hóa việc đặt tên, nhóm PHP đã chọn sử dụng thuật ngữ IntlDatePatternGenerator ngắn hơn.

Đây là một ví dụ trực tiếp từ RFC của nó:

$skeleton = "YYYYMMdd"; $today = DateTimeImmutable::createFromFormat('Ym-d', '2021-04-24'); $dtpg = new IntlDatePatternGenerator("de_DE"); $pattern = $dtpg->getBestPattern($skeleton); echo "de: ", IntlDateFormatter::formatObject($today, $pattern, "de_DE"), "n"; $dtpg = new IntlDatePatternGenerator("en_US"); $pattern = $dtpg->getBestPattern($skeleton), "n"; echo "en: ", IntlDateFormatter::formatObject($today, $pattern, "en_US"), "n"; /* de: 24.04.2021 en: 04/24/2021 */

Trong đoạn mã trên, biến khung xác định các định dạng ngày hoặc giờ cụ thể để sử dụng. Tuy nhiên, trình định dạng xử lý thứ tự của kết quả cuối cùng.

Hỗ trợ định dạng hình ảnh AVIF

AVIF, hoặc Định dạng tệp hình ảnh AV1, là một định dạng hình ảnh miễn phí bản quyền tương đối mới dựa trên định dạng mã hóa video AV1. Ngoài việc cung cấp khả năng nén cao hơn (và do đó kích thước tệp nhỏ hơn), nó còn hỗ trợ một số tính năng như độ trong suốt, HDR và hơn thế nữa.

Định dạng AVIF chỉ mới được chuẩn hóa gần đây (ngày 8 tháng 6 năm 2021). Điều đó đã mở đường cho các trình duyệt, chẳng hạn như Chrome 85+ và Firefox 86+, thêm hỗ trợ cho hình ảnh AVIF.

Phần mở rộng GD và xử lý hình ảnh của PHP 8.1 bổ sung hỗ trợ cho hình ảnh AVIF.

Tuy nhiên, để bao gồm chức năng này, bạn cần phải biên dịch phần mở rộng GD với hỗ trợ AVIF. Bạn có thể làm như vậy bằng cách chạy các lệnh bên dưới.

Đối với Debian / Ubuntu:

apt install libavif-dev

Đối với Fedora / RHEL:

dnf install libavif-devel

Điều đó sẽ cài đặt tất cả các phụ thuộc mới nhất. Tiếp theo, bạn có thể biên dịch hỗ trợ AVIF bằng cách chạy cờ --with-avif với tập lệnh ./configure .

./buildconf --force ./configure --enable-gd --with-avif

Nếu bạn đang bắt đầu một môi trường mới từ đầu, bạn cũng có thể bật các phần mở rộng PHP khác tại đây.

Sau khi cài đặt, bạn có thể kiểm tra xem hỗ trợ AVIF có được bật hay không bằng cách chạy lệnh sau trong thiết bị đầu cuối PHP của bạn:

php -i | grep AVIF

Nếu bạn đã cài đặt đúng AVIF, bạn sẽ thấy kết quả sau:

AVIF Support => enabled

Bạn cũng có thể sử dụng lệnh gọi gd_info() để truy xuất danh sách các tính năng GD, bao gồm cả việc chức năng Hỗ trợ AVIF có được bật hay không.

Phần mở rộng PHP 8.1 GD được cập nhật này cũng bổ sung thêm hai chức năng mới để làm việc với hình ảnh AVIF: imagecreatefromavifimageavif . Chúng hoạt động tương tự như các đối tác JPEG và PNG.

Hàm imagecreatefromavif trả về một phiên bản GdImage từ một hình ảnh AVIF nhất định. Sau đó, bạn có thể sử dụng phiên bản này để chỉnh sửa hoặc chuyển đổi hình ảnh.

Hàm imageavif khác xuất ra tệp hình ảnh AVIF. Ví dụ: bạn có thể sử dụng nó để chuyển đổi JPEG thành AVIF:

$image = imagecreatefromjpeg('image.jpeg'); imageavif($image, 'image.avif');

Bạn có thể đọc thêm về tính năng mới này trên trang GitHub của nó.

$_FILES: full_path Key mới để tải lên thư mục

PHP duy trì một số lượng lớn các biến được xác định trước để theo dõi nhiều thứ khác nhau. Một trong số chúng là biến $ _FILES chứa một mảng liên kết gồm các mục được tải lên qua phương thức HTTP POST.

Hầu hết các trình duyệt hiện đại đều hỗ trợ tải lên toàn bộ thư mục với các trường tải lên tệp HTML. Ngay cả PHP <8.1 cũng hỗ trợ chức năng này, nhưng có một lưu ý lớn. Bạn không thể tải lên một thư mục có cấu trúc thư mục chính xác hoặc các đường dẫn tương đối của nó vì PHP không chuyển thông tin này vào mảng $_FILES .

Điều đó thay đổi trong PHP 8.1 với việc bổ sung một khóa mới có tên là full_path vào mảng $_FILES . Sử dụng dữ liệu mới này, bạn có thể lưu trữ các đường dẫn tương đối hoặc sao chép cấu trúc thư mục chính xác trên máy chủ.

Bạn có thể kiểm tra thông tin này bằng cách xuất ra mảng $FILES bằng var_dump($_FILES); yêu cầu.

Tuy nhiên, hãy tiến hành một cách thận trọng nếu bạn đang sử dụng tính năng này. Đảm bảo rằng bạn bảo vệ khỏi các cuộc tấn công tải lên tệp tiêu chuẩn.

Hỗ trợ giải nén mảng cho mảng có khóa chuỗi

PHP 7.4 đã bổ sung hỗ trợ giải nén mảng với toán tử dàn trải mảng ( ). Nó hoạt động như một giải pháp thay thế nhanh hơn cho việc sử dụng hàm array_merge() . Tuy nhiên, tính năng này bị giới hạn ở các mảng có khóa số vì việc giải nén các mảng có khóa chuỗi gây ra xung đột trong khi hợp nhất các mảng với các khóa trùng lặp.

Tuy nhiên, PHP 8 đã thêm hỗ trợ cho các đối số được đặt tên, loại bỏ hạn chế này. Do đó, giải nén mảng giờ đây cũng sẽ hỗ trợ các mảng có khóa chuỗi bằng cách sử dụng cùng một cú pháp:

$array = [...$array1, ...$array2];

Ví dụ RFC này minh họa cách xử lý hợp nhất các mảng với các khóa chuỗi trùng lặp trong PHP 8.1:

$array1 = ["a" => 1]; $array2 = ["a" => 2]; $array = ["a" => 0, ...$array1, ...$array2]; var_dump($array); // ["a" => 2]

Ở đây, khóa chuỗi “a” xuất hiện ba lần trước khi hợp nhất thông qua giải nén mảng. Nhưng chỉ giá trị cuối cùng của nó thuộc về $array2 mới thắng.

Ký hiệu số bát phân rõ ràng

PHP hỗ trợ các hệ thống số khác nhau, bao gồm hệ thập phân (cơ số 10), nhị phân (cơ số 2), bát phân (cơ số 8) và hex (cơ số 16). Hệ thống chữ số thập phân là mặc định.

Nếu bạn muốn sử dụng bất kỳ hệ thống chữ số nào khác, thì bạn sẽ phải thêm tiền tố chuẩn cho mỗi số:

  • Tiền tố hex: 0x . (ví dụ: 17 = 0x11 )
  • Tiền tố nhị phân: 0b . (ví dụ: 3 = 0b11 )
  • Tiền tố bát phân: 0 . (ví dụ: 9 = 011 )

Bạn có thể thấy tiền tố của hệ thống số bát phân thay đổi như thế nào so với phần còn lại. Để chuẩn hóa mối quan tâm này, nhiều ngôn ngữ lập trình đang bổ sung hỗ trợ cho ký hiệu số bát phân rõ ràng: 0o hoặc 0O .

Bắt đầu với PHP 8.1, bạn có thể viết ví dụ được hiển thị ở trên (tức là số 9 trong cơ số 10) trong hệ thống số bát phân là 0o11 hoặc 0O11 .

0o16 === 14; // true 0o123 === 83; // true 0O16 === 14; // true 0O123 === 83; // true 016 === 0o16; // true 016 === 0O16; // true

Hơn nữa, tính năng mới này cũng hoạt động với dấu gạch dưới phân tách chữ số được giới thiệu trong PHP 7.4.

Đọc thêm về tính năng PHP 8.1 mới này trong RFC của nó.

Hỗ trợ thuật toán băm MurmurHash3 và xxHash

PHP 8.1 bổ sung hỗ trợ cho các thuật toán băm MurmurHash3 và xxHash. Chúng không được thiết kế để sử dụng mật mã, nhưng chúng vẫn cung cấp tính ngẫu nhiên, phân tán và duy nhất của đầu ra ấn tượng.

Các thuật toán băm mới này nhanh hơn hầu hết các thuật toán băm hiện có của PHP. Trên thực tế, một số biến thể của thuật toán băm này nhanh hơn thông lượng RAM.

Đăng kí để nhận thư mới

Vì PHP 8.1 cũng bổ sung hỗ trợ khai báo các tham số $options cụ thể cho thuật toán, bạn có thể thực hiện tương tự với các thuật toán mới này. Giá trị mặc định của đối số mới này là [] . Vì vậy, nó sẽ không ảnh hưởng đến bất kỳ hàm băm nào hiện có của chúng tôi.

Bạn có thể đọc thêm về các tính năng PHP 8.1 mới này trên các trang GitHub của họ: MurmurHash3, xxHash, Algorithm-specific $ options.

Hỗ trợ DNS qua HTTPS (DoH)

DNS-over-HTTPS (DoH) là một giao thức phân giải DNS thông qua giao thức HTTPS. Sử dụng HTTPS để mã hóa dữ liệu giữa máy khách và trình phân giải DNS, DoH tăng quyền riêng tư và bảo mật của người dùng bằng cách ngăn chặn các cuộc tấn công MitM.

Bắt đầu với PHP 8.1, bạn có thể sử dụng phần mở rộng Curl để chỉ định máy chủ DoH. Nó yêu cầu PHP được biên dịch với phiên bản libcurl 7.62+. Đó không phải là vấn đề đối với hầu hết các hệ điều hành phổ biến, bao gồm cả các bản phân phối Linux, vì chúng thường bao gồm Curl 7.68+.

Bạn có thể định cấu hình URL máy chủ DoH bằng cách chỉ định tùy chọn CURLOPT_DOH_URL .

$doh = curl_init('https://kinsta.com'); curl_setopt($doh, CURLOPT_DOH_URL, 'https://dns.google/dns-query'); curl_exec($doh);

Trong ví dụ trên, chúng tôi đã sử dụng máy chủ DNS công cộng của Google. Ngoài ra, hãy lưu ý việc sử dụng https:// trong tất cả các URL được sử dụng. Đảm bảo cấu hình điều này một cách hoàn hảo vì không có máy chủ DNS mặc định nào quay trở lại trong Curl.

Bạn cũng có thể chọn từ danh sách các máy chủ DoH công cộng có trong tài liệu Curl.

Hơn nữa, tham chiếu CURLOPT_DOH_URL của tài liệu Curl giải thích cách sử dụng triệt để các đối số khác nhau của nó.

Tải lên tệp từ chuỗi với CURLStringFile

Phần mở rộng PHP Curl hỗ trợ các yêu cầu HTTP (S) với tải lên tệp. Nó sử dụng lớp CURLFile để đạt được điều này, lớp này chấp nhận URI hoặc đường dẫn tệp, kiểu mime và tên tệp cuối cùng.

Tuy nhiên, với lớp CURLFile , bạn chỉ có thể chấp nhận đường dẫn tệp hoặc URI chứ không chấp nhận nội dung của chính tệp đó. Trong trường hợp bạn đã có tệp được tải lên trong bộ nhớ (ví dụ: hình ảnh đã xử lý, tài liệu XML, PDF), bạn phải sử dụng data:// URIs với mã hóa Base64.

Nhưng libcurl đã hỗ trợ một cách dễ dàng hơn để chấp nhận nội dung của tệp. Lớp CURLStringFile mới bổ sung hỗ trợ chính xác cho điều đó.

Bạn có thể đọc trang GitHub của nó để tìm hiểu thêm về cách nó được triển khai trong PHP 8.1.

Hằng MYSQLI_REFRESH_REPLICA mới

Phần mở rộng mysqli của PHP 8.1 thêm một hằng số mới có tên MYSQLI_REFRESH_REPLICA . Nó tương đương với hằng số MYSQLI_REFRESH_SLAVE hiện có.

Thay đổi này được hoan nghênh trong MySQL 8.0.23 để giải quyết sự phân biệt chủng tộc trong từ vựng công nghệ (các ví dụ phổ biến nhất bao gồm “nô lệ” và “chủ”).

Bạn nên lưu ý rằng hằng số cũ hơn không bị xóa hoặc không được dùng nữa. Các nhà phát triển và ứng dụng có thể tiếp tục sử dụng nó. Hằng số mới này chỉ là một lựa chọn cho các nhà phát triển và công ty muốn bỏ lại thuật ngữ như vậy.

Cải thiện hiệu suất với Bộ nhớ đệm kế thừa

Inheritance Cache là một bổ sung mới cho opcache giúp loại bỏ chi phí kế thừa lớp PHP.

Các lớp PHP được biên dịch và lưu trữ bởi opcache riêng biệt. Tuy nhiên, chúng đã được liên kết tại thời điểm chạy theo từng yêu cầu. Quá trình này có thể bao gồm một số kiểm tra tính tương thích và mượn các phương thức / thuộc tính / hằng số từ các lớp và đặc điểm cha.

Do đó, điều này mất thời gian đáng kể để thực thi, mặc dù kết quả là như nhau cho mỗi yêu cầu.

Thừa kế Cache liên kết tất cả các lớp phụ thuộc duy nhất (cha, giao diện, đặc điểm, kiểu thuộc tính, phương thức) và lưu trữ kết quả trong bộ nhớ dùng chung opcache. Vì điều này chỉ xảy ra một lần bây giờ, kế thừa yêu cầu ít hướng dẫn hơn.

Hơn nữa, nó loại bỏ các giới hạn đối với các lớp bất biến, chẳng hạn như các hằng số chưa được giải quyết, các thuộc tính đã định và kiểm tra kiểu hiệp phương sai. Do đó, tất cả các lớp được lưu trữ trong opcache là không thể thay đổi, giảm hơn nữa số lượng lệnh được yêu cầu.

Nói chung, nó hứa hẹn những lợi ích hiệu suất đáng kể. Dimitry Stogov, tác giả của bản vá này, nhận thấy rằng nó đã cho thấy sự cải thiện 8% trên Symfony cơ sở “Hello, World!” chương trình. Chúng tôi rất nóng lòng để kiểm tra nó trong các điểm chuẩn PHP sau đây của chúng tôi.

Cú pháp có thể gọi hạng nhất

PHP 8.1 bổ sung cú pháp có thể gọi hạng nhất để thay thế các bảng mã hiện có bằng cách sử dụng chuỗi và mảng. Bên cạnh việc tạo ra một Closure rõ ràng hơn, cú pháp mới này cũng có thể truy cập được bằng các công cụ phân tích tĩnh và tôn trọng phạm vi đã khai báo.

Dưới đây là một số ví dụ được lấy từ RFC:

$fn = Closure::fromCallable('strlen'); $fn = strlen(...); $fn = Closure::fromCallable([$this, 'method']); $fn = $this->method(...) $fn = Closure::fromCallable([Foo::class, 'method']); $fn = Foo::method(...);

Ở đây, tất cả các cặp biểu thức là tương đương. Cú pháp dấu ba chấm ( ) tương tự như cú pháp giải nén đối số ( ...$args ). Ngoại trừ ở đây, các đối số vẫn chưa được điền vào.

Những thay đổi trong PHP 8.1

PHP 8.1 cũng bao gồm các thay đổi đối với cú pháp và tính năng hiện có của nó. Hãy thảo luận về chúng:

PHP Interactive Shell Yêu cầu Phần mở rộng dòng đọc

Phần mở rộng dòng đọc của PHP cho phép các tính năng tương tác của trình bao như điều hướng, tự động hoàn thành, chỉnh sửa, v.v. Mặc dù đi kèm với PHP nhưng nó không được bật theo mặc định.

Bạn có thể truy cập trình bao tương tác PHP bằng cách sử dụng tùy chọn dòng lệnh -a của PHP CLI:

php -a Interactive shell php > php > echo "Hello"; Hello php > function test() { php { echo "Hello"; php { } php > test(); Hello

Trước PHP 8.1, bạn có thể mở trình bao tương tác bằng PHP CLI ngay cả khi không bật tiện ích mở rộng dòng đọc. Như mong đợi, các tính năng tương tác của shell không hoạt động, khiến tùy chọn -a trở nên vô nghĩa.

Trong PHP 8.1 CLI, trình bao tương tác thoát ra với thông báo lỗi nếu bạn chưa bật tiện ích mở rộng dòng đọc.

php -a Interactive shell (-a) requires the readline extension.

Chế độ lỗi mặc định của MySQLi được đặt thành ngoại lệ

Trước phiên bản PHP 8.1, MySQLi được mặc định là không để xảy ra lỗi. Hành vi này thường dẫn đến mã không tuân theo việc xử lý Lỗi / Ngoại lệ nghiêm ngặt. Các nhà phát triển đã phải triển khai các chức năng xử lý lỗi rõ ràng của riêng họ.

PHP 8.1 thay đổi hành vi này bằng cách đặt chế độ báo cáo lỗi mặc định của MySQLi để đưa ra một ngoại lệ.

Fatal error: Uncaught mysqli_sql_exception: Connection refused in ...:...

Vì đây là một thay đổi đột phá, đối với các phiên bản PHP <8.1, bạn nên đặt chế độ xử lý lỗi một cách rõ ràng bằng cách sử dụng hàm mysqli_report trước khi thực hiện kết nối MySQLi đầu tiên. Ngoài ra, bạn có thể làm tương tự bằng cách chọn giá trị báo cáo lỗi bằng cách khởi tạo một mysqli_driver .

RFC tuân theo một thay đổi tương tự được giới thiệu trong PHP 8.0.

Kết thúc dòng có thể tùy chỉnh cho các chức năng viết CSV

Trước PHP 8.1, các hàm viết CSV tích hợp sẵn của PHP, fputcsvSplFileObject::fputcsv , được mã hóa cứng để thêm n (hoặc ký tự Line-Feed) vào cuối mỗi dòng.

PHP 8.1 bổ sung hỗ trợ cho một tham số mới có tên eol cho các hàm này. Bạn có thể sử dụng nó để chuyển một ký tự cuối dòng có thể định cấu hình. Theo mặc định, nó vẫn sử dụng ký tự n . Vì vậy, bạn có thể tiếp tục sử dụng nó trong mã hiện có của mình.

Quy tắc thoát ký tự tiêu chuẩn áp dụng cho việc sử dụng ký tự cuối dòng. Nếu bạn muốn sử dụng r , n hoặc rn làm ký tự EOL, bạn phải đặt chúng trong dấu ngoặc kép.

Đây là trang GitHub theo dõi thay đổi mới này.

Các giới hạn của nhà điều hành version_compare mới

version_compare() của PHP so sánh hai chuỗi số phiên bản. Hàm này chấp nhận một đối số thứ ba tùy chọn được gọi là operator để kiểm tra một mối quan hệ cụ thể.

Mặc dù không được đề cập rõ ràng trong tài liệu, trước PHP 8.1, bạn có thể đặt tham số này thành giá trị một phần (ví dụ: g , l , n ) mà không gặp lỗi.

PHP 8.1 bổ sung các hạn chế chặt chẽ hơn đối với đối số operator của hàm version_compare() để khắc phục tình trạng này. Các toán tử duy nhất bạn có thể sử dụng bây giờ là:

  • == , = , và eq
  • ! = , <>ne
  • >gt
  • > =ge
  • <lt
  • <=le

Không còn giá trị toán tử từng phần.

Cần một giải pháp lưu trữ mang lại cho bạn lợi thế cạnh tranh? Kinsta giúp bạn bao phủ bởi tốc độ đáng kinh ngạc, bảo mật hiện đại và tự động mở rộng quy mô. Kiểm tra các kế hoạch của chúng tôi

Các chức năng mã hóa và giải mã HTML Bây giờ Sử dụng ENT_QUOTES | ENT_SUBSTITUTE

Các thực thể HTML là các biểu diễn dạng văn bản của các ký tự mà nếu không sẽ được hiểu là HTML. Hãy nghĩ về các ký tự như <> được sử dụng để xác định các thẻ HTML (ví dụ: <a> , <h3> , <script> ).

Thực thể HTML cho < is & lt; (nhỏ hơn ký hiệu) và >& gt; (lớn hơn ký hiệu).

Lưu ý: Xóa khoảng cách giữa “&” và “amp.”

Bạn có thể sử dụng các thực thể HTML này một cách an toàn trong tài liệu HTML mà không cần kích hoạt công cụ kết xuất của trình duyệt.

Ví dụ: & lt;script& gt; sẽ hiển thị dưới dạng <script> trong trình duyệt, thay vì được hiểu là thẻ HTML.

Trước PHP 8.1, các hàm htmlspecialchars () và htmlentities () đã chuyển đổi các ký hiệu như " , < , >& thành các thực thể HTML tương ứng của chúng. Nhưng chúng không chuyển đổi ký tự trích dẫn đơn ( ' ) thành thực thể HTML của nó theo mặc định Hơn nữa, họ trả về một chuỗi trống nếu có UTF-8 không đúng định dạng trong văn bản.

Trong PHP 8.1., Các chức năng mã hóa và giải mã HTML này (và các chức năng liên quan của chúng) cũng sẽ chuyển đổi các ký tự trích dẫn đơn lẻ thành thực thể HTML của chúng theo mặc định.

Và nếu văn bản đã cho có các ký tự không hợp lệ, các hàm sẽ thay thế chúng bằng một ký tự thay thế Unicode (�) thay vì trả về một chuỗi trống. PHP 8.1 hoàn thành điều này bằng cách thay đổi chữ ký của các hàm này thành ENT_QUOTES | ENT_SUBSTITUTE thay vì ENT_COMPAT theo mặc định.

Hầu hết các khuôn khổ đã sử dụng ENT_QUOTES làm giá trị cờ mặc định. Vì vậy, bạn sẽ không thấy nhiều sự khác biệt do thay đổi này. Tuy nhiên, cờ ENT_SUBSTITUTE mới không được sử dụng rộng rãi. PHP 8.1 sẽ khiến các ký tự UTF-8 không hợp lệ được thay thế bằng ký tự � thay vì trả về một chuỗi trống.

Cảnh báo về cuộc gọi hàm nhỏ gọn bất hợp pháp

Hàm compact() của PHP rất tiện dụng. Bạn có thể sử dụng nó để tạo một mảng với các biến bằng cách sử dụng tên và giá trị của chúng.

Ví dụ, hãy xem xét đoạn mã sau:

$animal = 'Cat'; $sound = 'Meow'; $region = 'Istanbul'; compact('animal', 'sound', 'region'); // ['animal' => "Cat", 'sound' => "Meow", 'region' => "Istanbul"]

Tài liệu của hàm compact nói rằng nó sẽ chỉ chấp nhận các tham số chuỗi hoặc giá trị mảng có giá trị chuỗi. Tuy nhiên, trước PHP 7.3, bất kỳ chuỗi nào không được đặt sẽ bị bỏ qua một cách âm thầm.

PHP 7.3 đã sửa đổi hàm compact() để đưa ra thông báo nếu bạn sử dụng các biến không xác định. PHP 8.1 tiến thêm một bước nữa và đưa ra một cảnh báo.

Bạn có thể đọc trang GitHub của nó để hiểu về cách thức thay đổi này xảy ra.

Chuyển đổi mới từ Tài nguyên sang Đối tượng Lớp

Một trong những mục tiêu dài hạn của PHP là chuyển từ tài nguyên sang các đối tượng lớp tiêu chuẩn.

Vì lý do lịch sử, các đối tượng tài nguyên được sử dụng rộng rãi trong các ứng dụng PHP. Do đó, việc di chuyển tài nguyên sang các đối tượng lớp cần càng ít gián đoạn càng tốt. PHP 8.1 di chuyển năm tài nguyên như vậy:

Tài nguyên file_info di chuyển sang các đối tượng finfo

Lớp finfo của PHP cung cấp giao diện hướng đối tượng cho các hàm fileinfo . Tuy nhiên, việc sử dụng các hàm finfo trả về các đối tượng resource với kiểu file_info chứ không phải là một thể hiện của chính lớp finfo .

PHP 8.1 sửa lỗi bất thường này.

Tài nguyên IMAP được di chuyển sang IMAPConnection

Phù hợp với mục tiêu di chuyển tài nguyên sang đối tượng, lớp IMAPConnection mới giảm thiểu những thay đổi có thể xảy ra khi PHP cuối cùng sửa đổi chi tiết triển khai của lớp.

Lớp mới này cũng được khai báo là final , vì vậy bạn không được phép extend nó.

Đọc thêm về cách triển khai trên trang GitHub.

Tài nguyên kết nối FTP bây giờ là FTPConnection

Trong PHP <8.1, nếu bạn tạo kết nối FTP với các ftp_connect() hoặc ftp_ssl_connect() , bạn sẽ lấy lại một đối tượng tài nguyên kiểu ftp .

PHP 8.1 thêm lớp FTPConnection mới để khắc phục điều đó. Và giống như với lớp IMAPConnection , nó cũng được khai báo final để ngăn không cho nó được mở rộng.

Đọc thêm về cách triển khai trên trang GitHub.

Số nhận dạng phông chữ được di chuyển sang đối tượng lớp GdFont

Phần mở rộng GD của PHP cung cấp hàm imageeloadfont () để tải một bitmap do người dùng xác định và trả về ID tài nguyên nhận dạng phông chữ của nó (một số nguyên).

Trong PHP 8.1, hàm này thay vào đó sẽ trả về một cá thể lớp GdFont . Hơn nữa, để làm cho việc di chuyển không gặp rắc rối, tất cả các hàm trước đây đã chấp nhận ID tài nguyên từ imageloadfont() bây giờ sẽ nhận các đối tượng lớp GdFont mới.

Đọc thêm về việc di chuyển này trên trang GitHub của nó.

Tài nguyên LDAP được di chuyển sang đối tượng

LDAP, hoặc Giao thức truy cập thư mục nhẹ, được sử dụng để truy cập “Máy chủ thư mục”. Giống như cấu trúc thư mục đĩa cứng, nó là một cơ sở dữ liệu duy nhất chứa dữ liệu trong cấu trúc cây.

PHP bao gồm một phần mở rộng LDAP chấp nhận hoặc trả lại các đối tượng tài nguyên trước PHP 8.1. Tuy nhiên, tất cả chúng đã được di chuyển liền mạch sang các phiên bản lớp mới ngay bây giờ. Các loại tài nguyên đã được chuyển đổi là:

  • ldap link tài nguyên tới LDAPConnection
  • ldap result tài nguyên kết quả thành đối tượng lớp LDAPResult
  • ldap result entry đối tượng lớp LDAPResultEntry

Đi qua trang GitHub của nó để hiểu rõ hơn về quá trình di chuyển này.

Tài nguyên Pspell hiện là đối tượng lớp

Phần mở rộng Pspell của PHP cho phép bạn kiểm tra lỗi chính tả và gợi ý từ.

PHP <8.1 đã sử dụng các kiểu đối tượng tài nguyên pspell config pspell số nhận dạng số nguyên. Hai đối tượng tài nguyên này hiện được thay thế bằng các đối tượng lớp PSpellDictionaryPSpellConfig .

Giống như các lần di chuyển trước đó, tất cả các hàm Pspell đã được chấp nhận trước đó hoặc đã trả về các định danh đối tượng tài nguyên sẽ nhận các thể hiện đối tượng lớp mới.

Tham khảo trang GitHub của nó để biết thêm thông tin.

Không dùng nữa trong PHP 8.1

PHP 8.1 không dùng nhiều tính năng trước đây của nó. Danh sách sau cung cấp tổng quan ngắn gọn về các chức năng mà PHP 8.1 không dùng nữa:

Không thể chuyển null sang các tham số chức năng bên trong không thể rỗng

Kể từ PHP 8.0, các hàm bên trong của nó sẽ âm thầm chấp nhận các giá trị null ngay cả đối với các đối số không thể null. Điều tương tự cũng không áp dụng đối với các hàm do người dùng xác định – chúng chỉ chấp nhận null đối với các đối số có thể null.

Ví dụ, hãy xem xét cách sử dụng này:

var_dump( str_contains ("foobar", null)); // bool( true )

Ở đây, giá trị null được chuyển đổi âm thầm thành một chuỗi rỗng. Do đó, kết quả trả về true .

RFC này nhằm mục đích đồng bộ hóa hành vi của các chức năng bên trong bằng cách đưa ra cảnh báo không dùng nữa trong PHP 8.1.

var_dump(str_contains("foobar", null)); // Deprecated: Passing null to argument of type string is deprecated

Việc không dùng nữa sẽ trở thành TypeError trong phiên bản PHP chính tiếp theo (tức là PHP> = 9.0), làm cho hoạt động của các hàm nội bộ nhất quán với các hàm do người dùng định nghĩa.

Hạn chế sử dụng $GLOBALS

Biến $GLOBALS của PHP cung cấp một tham chiếu trực tiếp đến bảng ký hiệu bên trong của nó. Hỗ trợ chức năng này rất phức tạp và ảnh hưởng đến hiệu suất hoạt động của mảng. Thêm vào đó, nó hiếm khi được sử dụng.

Theo RFC, việc sửa đổi gián tiếp $GLOBALS không còn được phép nữa. Thay đổi này không tương thích ngược.

Tác động của thay đổi này là tương đối thấp:

Trong các gói trình soạn nhạc 2k hàng đầu, tôi đã tìm thấy 23 trường hợp sử dụng $ GLOBALS mà không cần tham khảo trực tiếp nó. Dựa trên kiểm tra lướt qua, chỉ có hai trường hợp $ GLOBALS không được sử dụng theo cách chỉ đọc.

Tuy nhiên, việc sử dụng $GLOBALS ở chế độ chỉ đọc vẫn tiếp tục hoạt động như bình thường. Những gì không còn được hỗ trợ sẽ được viết cho $GLOBALS nói chung. Do đó, bạn có thể mong đợi một chút ảnh hưởng về hiệu suất, đặc biệt là khi làm việc với các mảng PHP thông thường.

Khai báo loại trả lại cho các chức năng nội bộ

PHP 8.0 cho phép các nhà phát triển khai báo các tham số và kiểu trả về cho hầu hết các hàm và phương thức bên trong. Điều này có thể xảy ra nhờ các RFC khác nhau, chẳng hạn như lỗi kiểu nhất quán cho các chức năng nội bộ, Kiểu liên minh 2.0 và Kiểu hỗn hợp v2.

Tuy nhiên, có nhiều trường hợp thông tin loại có thể bị thiếu. Một số trong số chúng bao gồm một kiểu có tài nguyên, tham số chuyển qua-tham chiếu, kiểu trả về của phương thức không phải cuối cùng và các hàm hoặc phương thức không phân tích cú pháp tham số theo các quy tắc chung. Bạn có thể đọc chi tiết chính xác trong RFC của nó.

RFC này chỉ giải quyết vấn đề với kiểu trả về không phải là phương thức cuối cùng. Tuy nhiên, thay vì loại bỏ hoàn toàn nó ngay lập tức, nhóm PHP cung cấp một đường dẫn di chuyển dần dần để cập nhật cơ sở mã của bạn với các kiểu trả về phương thức có liên quan.

Các kiểu trả về phương thức nội bộ không phải cuối cùng – khi có thể – được khai báo tạm thời trong PHP 8.1 và chúng sẽ được thực thi trong PHP 9.0. Điều đó có nghĩa là trong các phiên bản PHP 8.x, thông báo “không được dùng nữa” được đưa ra trong quá trình kiểm tra kế thừa khi một phương thức nội bộ bị ghi đè theo cách mà các kiểu trả về không tương thích và PHP 9.0 sẽ tạo ra những lỗi nghiêm trọng này.

Nếu bạn thấy thông báo ngừng sử dụng này sau khi cập nhật lên PHP 8.1, hãy đảm bảo cập nhật các loại trả về phương thức của bạn.

Giao diện có thể nối tiếp hóa không được dùng nữa

PHP 7.4 đã giới thiệu cơ chế tuần tự hóa đối tượng tùy chỉnh với hai phương thức ma thuật mới: __serialize()__unserialize() . Các phương pháp mới này nhằm mục đích cuối cùng là thay thế giao diện Serializable bị hỏng.

RFC này đề xuất hoàn thiện quyết định đó bằng cách đưa ra một kế hoạch để loại bỏ Serializable cuối cùng.

Trong PHP 8.1, nếu bạn triển khai giao diện Serializable mà không triển khai các phương thức __serialize()__unserialize() , PHP sẽ đưa ra cảnh báo “Không được chấp nhận”.

Deprecated: The Serializable interface is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) in ... on line ...

Nếu bạn đang hỗ trợ PHP <7.4PHP> = 7.4 , bạn nên triển khai cả giao diện Serializable và các phương thức ma thuật mới. Trên các phiên bản PHP> = 7.4 , các phương thức ma thuật sẽ được ưu tiên hơn.

Chuyển đổi không tương thích int float đổi không được dùng nữa

PHP là một ngôn ngữ được gõ động. Như vậy, có nhiều trường hợp tự nhiên xảy ra cưỡng chế kiểu. Hầu hết các cưỡng chế này đều vô hại và siêu tiện lợi.

Tuy nhiên, khi một số thực được chuyển đổi thành số nguyên , nó thường liên quan đến việc mất dữ liệu. Ví dụ: khi float 3.14 được chuyển đổi thành số nguyên 3 , nó sẽ mất giá trị phân số.

Điều tương tự cũng xảy ra khi float nằm ngoài phạm vi số nguyên của nền tảng hoặc khi chuỗi float được chuyển đổi thành số nguyên.

PHP 8.1 khắc phục hành vi này và đưa kiểu động của nó bắt buộc phù hợp hơn với hầu hết các ngôn ngữ lập trình hiện đại. Mục đích là làm cho những cưỡng chế như vậy có thể dự đoán được và trực quan.

Trong PHP 8.1, bạn sẽ thấy thông báo ngừng sử dụng khi một float không tương thích bị ép buộc hoàn toàn thành int . Nhưng điều gì tạo nên một float tương thích với số nguyên? RFC trả lời câu hỏi này:

Một float được cho là tương thích với số nguyên nếu có các đặc điểm sau:

  • Là một số (tức là không phải NaN hoặc Infinity)
  • Nằm trong phạm vi của một số nguyên PHP (phụ thuộc vào nền tảng)
  • Không có phần phân số

Thông báo ngừng sử dụng này sẽ nâng cấp lên TypeError trong phiên bản PHP chính tiếp theo (tức là PHP 9.0).

Phương thức mysqli::get_client_infomysqli_get_client_info($param) được dùng nữa

API máy khách MySQL định nghĩa hai hằng số: client_info (một chuỗi) và client_version (một int). MySQL Native Driver (MySQLnd) là một phần của nguồn PHP chính thức và gắn các hằng số này vào phiên bản PHP. Trong libmysql, chúng đại diện cho phiên bản thư viện máy khách tại thời điểm biên dịch.

Trước PHP 8.1, mysqli đã hiển thị các hằng số này theo 4 cách: thuộc tính mysqli_driver , thuộc tính mysqli properties , mysqli_get_client_info() và phương thức mysqli::get_client_info . Tuy nhiên, không có phương pháp nào cho client_version .

MySQLnd hiển thị các hằng số này theo 2 cách đối với PHP: một hằng số và một lời gọi hàm. Để hợp nhất các phương thức truy cập mysqli với hai tùy chọn giống nhau này, PHP 8.1 sẽ không dùng hai tùy chọn khác sau:

  • phương thức get_client_info trong lớp mysqli . Thay vào đó, bạn chỉ có thể sử dụng hàm mysqli_get_client_info() .
  • mysqli_get_client_info() với các tham số. Gọi hàm mà không có bất kỳ tham số nào để tránh thông báo không dùng nữa.

Đọc thêm về việc ngừng sử dụng này trên trang GitHub.

Tất cả các mhash*() (Phần mở rộng băm) không được dùng nữa

PHP 5.3 tích hợp các mhash*() vào ext/hash như một lớp tương thích cho ext/mhash . Sau đó, PHP 7.0 đã loại bỏ ext/mhash .

Không giống như các hash_*() , các mhash*() không phải lúc nào cũng có sẵn. Bạn phải bật chúng một cách riêng biệt trong khi cấu hình PHP.

Trong PHP 7.4, phần mở rộng băm được đóng gói cùng với PHP, làm cho nó trở thành phần mở rộng mặc định cho PHP. Tuy nhiên, nó vẫn hỗ trợ bật tùy chọn --enable-mhash vì lý do tương thích.

Nhóm PHP đã quyết định không dùng các hàm mhash * () trong PHP 8.1 và xóa chúng hoàn toàn trong PHP 9.0. Các hàm không được dùng nữa là mhash() , mhash_keygen_s2k() , mhash_count() , mhash_get_block_size()mhash_get_hash_name() . Bạn có thể sử dụng chức năng mở rộng ext/hash tiêu chuẩn thay cho chúng.

Cả filter.defaultfilter.default_options Cài đặt INI không được dùng nữa

Cài đặt filter.default INI của PHP cho phép bạn áp dụng bộ lọc cho tất cả các siêu toàn cầu PHP – tức là dữ liệu GPCRS ( $_GET , $_POST , $_COOKIE , $_REQUEST$_SERVER ).

Ví dụ: bạn có thể đặt filter.default=magic_quotes hoặc filter.default=add_slashes (dựa trên phiên bản PHP) để hồi sinh tính năng trích dẫn ma thuật gây tranh cãi và không an toàn của PHP (đã bị loại bỏ trong PHP 5.4).

Cài đặt INI filter.default cung cấp chức năng bổ sung bằng cách cho phép nhiều bộ lọc hơn, khiến nó thậm chí còn tồi tệ hơn. Ví dụ: tùy chọn khác của nó – filter.default=special_chars – chỉ cho phép các dấu ngoặc kép cho HTML. Có ít nhận thức hơn về các cài đặt này.

PHP 8.1 sẽ đưa ra cảnh báo không dùng nữa nếu filter.default được đặt thành bất kỳ giá trị nào khác ngoài unsafe_raw (mặc định). Bạn sẽ không thấy thông báo ngừng sử dụng riêng cho filter.default_options , nhưng PHP 9.0 sẽ xóa cả hai cài đặt INI này.

Thay vào đó, bạn có thể bắt đầu sử dụng hàm filter_var (). Nó lọc các biến với bộ lọc được chỉ định.

Không chấp autovivification trên false

PHP cho phép tự động hóa (tự động tạo mảng từ các giá trị sai). Tính năng này cực kỳ hữu ích nếu biến không được xác định.

Tuy nhiên, không phải là lý tưởng để tự động tạo một mảng khi giá trị là false hoặc null.

RFC này không cho phép tự động xác minh khỏi các giá trị sai. Tuy nhiên, lưu ý rằng vẫn cho phép tự động xác minh từ các biến không xác định và null.

Trong PHP 8.1, việc thêm vào một biến kiểu false sẽ phát ra thông báo không dùng nữa:

Deprecated: Automatic conversion of false to array is deprecated in

PHP 9.0 sẽ gây ra một lỗi nghiêm trọng cho cùng một lỗi, lỗi này giống hệt với các kiểu vô hướng khác.

mysqli_driver->driver_version được dùng nữa

Thuộc tính mysqli_driver-> driver_version của tiện ích mở rộng MySQLi đã không được cập nhật trong 13 năm. Mặc dù có nhiều thay đổi đối với trình điều khiển kể từ đó, nó vẫn trả về giá trị phiên bản trình điều khiển cũ, làm cho thuộc tính này trở nên vô nghĩa.

Trong PHP 8.1, thuộc tính mysqli_driver-> driver_version không được dùng nữa.

Những thay đổi nhỏ khác

Có nhiều điểm không dùng nữa trong PHP 8.1. Liệt kê tất cả chúng ở đây sẽ là một bài tập mệt mỏi. Chúng tôi khuyên bạn nên kiểm tra trực tiếp RFC để biết những lỗi nhỏ này.

Trang GitHub của PHP cũng bao gồm hướng dẫn LƯU Ý NÂNG CẤP PHP 8.1. Nó liệt kê tất cả những thay đổi cơ bản mà bạn nên xem xét trước khi nâng cấp lên PHP 8.1.

Bản tóm tắt

PHP 8.1 tốt hơn so với người tiền nhiệm của nó, đó là một thành tích không nhỏ. Chúng tôi nghĩ rằng các tính năng thú vị nhất của PHP 8.1 là Enums, Fibers, Pure Intersection type và nhiều cải tiến về hiệu suất của nó. Ngoài ra, chúng tôi không thể chờ đợi để đưa PHP 8.1 thông qua các bước của nó và đánh giá các khuôn khổ PHP và CMS khác nhau.

Đảm bảo đánh dấu bài đăng trên blog này để bạn tham khảo trong tương lai.

Bạn yêu thích tính năng PHP 8.1 nào? Chia sẻ suy nghĩ của bạn với cộng đồng trong phần bình luận bên dưới.


Tiết kiệm thời gian, chi phí và tối đa hóa hiệu suất trang web với:

  • Trợ giúp tức thì từ các chuyên gia lưu trữ WordPress, 24/7.
  • Tích hợp Cloudflare Enterprise.
  • Tiếp cận khán giả toàn cầu với 34 trung tâm dữ liệu trên toàn thế giới.
  • Tối ưu hóa với Giám sát Hiệu suất Ứng dụng được tích hợp sẵn của chúng tôi.

Tất cả những điều đó và hơn thế nữa, trong một kế hoạch không có hợp đồng dài hạn, hỗ trợ di chuyển và đảm bảo hoàn tiền trong 30 ngày. Kiểm tra các kế hoạch của chúng tôi hoặc nói chuyện với bộ phận bán hàng để tìm ra kế hoạch phù hợp với bạn.