Đây là nơi quảng cáo sẽ đến. Tuy nhiên, thay vào đó, tôi muốn hướng bạn tới trang Nhà tài trợ GitHub của tôi. Nếu bạn là độc giả thường xuyên và nội dung của tôi đang giúp ích cho bạn, bạn có thể xem xét tài trợ một lần hoặc hàng tháng. Nếu bạn là một công ty đang tìm kiếm các vị trí đặt quảng cáo chuyên dụng trên blog này hoặc bản tin của tôi, bạn có thể gửi email cho tôi theo địa chỉ brendt@stitcher. io
PHP8. 1 được phát hành vào ngày 25 tháng 11 năm 2021. Hiện tại nó là phiên bản PHP mới nhất. Trong bài đăng này, chúng ta sẽ lần lượt xem xét tất cả các tính năng, cải tiến hiệu suất, thay đổi và ngừng sử dụng
Các tính năng mới
Như với mọi bản phát hành, PHP 8. 1 thêm một số tính năng mới hay. Hãy nhớ rằng danh sách này sẽ tăng lên trong năm
👍
👍
👍 0
Enums RFC
Enums sẽ được thêm vào trong PHP 8. 1. Nếu bạn không chắc chúng có thể được sử dụng để làm gì, bạn có thể đọc về chúng tại đây
Thêm enums sẽ là một cải tiến đáng kể trong PHP, vì vậy tôi rất mong đợi được thấy enums xuất hiện trong PHP 8. 1. Để cung cấp cho bạn bản xem trước nhanh về giao diện của chúng, đây là một mẫu mã
enum Status {
case Pending;
case Active;
case Archived;
}
Và đây là cách chúng sẽ được sử dụng
class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
Bạn có thể tìm thấy một phân tích chuyên sâu về cách sử dụng enums trong bài viết này
sợi RFC
Sợi — còn gọi là "luồng xanh" — là một cơ chế cấp thấp để quản lý tính song song. Bạn có thể sẽ không sử dụng chúng trực tiếp trong các ứng dụng của mình, nhưng các framework như Amphp và ReactPHP sẽ sử dụng chúng rộng rãi
Đây là một ví dụ đơn giản về việc sử dụng sợi
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
Nếu bạn muốn đọc thêm về sợi, những gì chúng có thể và không thể làm, bạn có thể đọc bài đăng này
Xây dựng một máy phát tia lửa điện
Cải thiện hiệu suất PR
Dmitry Stogov đã thêm một số cải tiến cho opcache, ông gọi nó là "bộ đệm kế thừa". Tính năng này cho phép các liên kết giữa các lớp được lưu vào bộ đệm, giống như các lớp được liên kết có thể được tải trước kể từ PHP 7. 4
Dmitry báo cáo hiệu suất tăng từ 5% đến 8% nhờ thay đổi này, một chi tiết nhỏ thú vị cần chú ý trong PHP 8. 1
Giải nén mảng bằng các khóa chuỗi RFC
Giải nén mảng đã được cho phép trong PHP 7. 4, nhưng nó chỉ hoạt động với các phím số. Lý do khóa chuỗi không được hỗ trợ trước đây là do không có bất kỳ sự đồng thuận nào về cách hợp nhất các mảng trùng lặp. RFC giải quyết vấn đề này một cách rõ ràng bằng cách tuân theo ngữ nghĩa của
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
2$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
3 trong trình khởi tạo RFC
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
RFC này cho phép bạn sử dụng từ khóa
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
3 trong các định nghĩa hàm làm tham số mặc định, cũng như trong các đối số thuộc tính và các vị trí khácclass MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
Bạn có thể đọc tất cả về tính năng này trong bài đăng chuyên dụng này
Thuộc tính chỉ đọc RFC
Thuộc tính lớp có thể được đánh dấu là chỉ đọc, nghĩa là chúng chỉ có thể được viết một lần
________số 8_______Cố gắng thay đổi thuộc tính chỉ đọc sau khi nó đã được khởi tạo sẽ dẫn đến lỗi
$post = new Post['Title', /* … */];
$post->title = 'Other';
Error: Cannot modify readonly property Post::$title
Nếu bạn muốn tìm hiểu sâu hơn về các thuộc tính chỉ đọc, bạn có thể đọc bài đăng tiếp theo của tôi
Cú pháp có thể gọi hạng nhất RFC
Bây giờ, bạn có thể đóng từ một hàm có thể gọi được bằng cách gọi hàm có thể gọi được đó và chuyển nó
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
5 làm đối số của nófunction foo[int $a, int $b] { /* … */ }
$foo = foo[...];
$foo[a: 1, b: 2];
Các loại giao lộ thuần túy RFC
Bạn đã biết về và các loại giao lộ là một tính năng tương tự. Trong trường hợp các loại liên kết yêu cầu đầu vào là một trong các loại đã cho, các loại giao nhau yêu cầu đầu vào phải là tất cả các loại đã chỉ định. Các loại giao lộ đặc biệt hữu ích khi bạn đang làm việc với nhiều giao diện
function generateSlug[HasTitle&HasId $post] {
return strtolower[$post->getTitle[]] . $post->getId[];
}
Nếu bạn thích phong cách lập trình này, bạn cần tạo một giao diện mới
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
6 và triển khai nó trong $fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
7, các loại giao lộ sẽ loại bỏ chi phí đóLoại RFC $fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
8 mới
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
Loại
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
8 có thể được sử dụng để chỉ ra rằng một chức năng sẽ thực sự dừng dòng chương trình. Điều này có thể được thực hiện bằng cách đưa ra một ngoại lệ, gọi $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
0 hoặc các chức năng tương tự khácfunction dd[mixed $input]: never
{
// dump
exit;
}
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
8 khác với $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
2 ở chỗ $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
2 vẫn cho phép chương trình tiếp tục. Đây có vẻ như là một tính năng mới lạ nhưng nó thực sự là một tính năng khá hữu ích cho các máy phân tích tĩnhChức năng $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
4 mới RFC
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
Bạn có thể đã phải đối phó với điều này một lần trong một thời gian. xác định xem các khóa của mảng có theo thứ tự số hay không, bắt đầu từ chỉ mục 0. Giống như
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
5 quyết định xem một mảng nên được mã hóa dưới dạng mảng hay đối tượngPHP8. 1 thêm một hàm tích hợp để xác định xem một mảng có phải là một danh sách với các ngữ nghĩa đó hay không
class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
0Bạn có muốn cập nhật về PHP 8. 1 phát triển?
Đăng ký emailHằng số lớp cuối cùng RFC
Hằng số lớp trong PHP có thể bị ghi đè trong quá trình kế thừa
class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
1Kể từ PHP 8. 1, bạn có thể đánh dấu các hằng số như vậy là
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
6 để ngăn chặn điều nàyclass Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
2Chức năng $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
7 mới RFC
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
PHP8. 1 thêm các hàm
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
7 và $array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
9 để bắt buộc đồng bộ hóa các thay đổi của tệp vào đĩa và đảm bảo bộ đệm ghi của hệ điều hành đã được xóa trước khi quay lạiclass Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
3Vì đồng bộ hóa đĩa là hoạt động của hệ thống tệp nên hàm
$array1 = ["a" => 1];
$array2 = ["b" => 2];
$array = ["a" => 0, ...$array1, ...$array2];
var_dump[$array]; // ["a" => 1, "b" => 2]
7 sẽ chỉ hoạt động trên các luồng tệp đơn giản. Cố gắng đồng bộ hóa các luồng không phải tệp sẽ phát ra cảnh báoKý hiệu số nguyên bát phân rõ ràng RFC
Bây giờ bạn có thể sử dụng
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
1 và class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
2 để biểu thị các số bát phân. Ký hiệu trước đó bằng cách đặt trước một số bằng class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
3 vẫn hoạt động tốtclass Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
4Thay đổi đột phá
Trong khi PHP 8. 1 là một phiên bản nhỏ, sẽ có một số thay đổi về mặt kỹ thuật có thể là một thay đổi đột phá và cả việc không dùng nữa. Hãy thảo luận từng cái một
Các kiểu trả về phương thức nội bộ RFC
Rất có thể bạn sẽ gặp phải thông báo không dùng nữa này khi nâng cấp lên PHP 8. 1
class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
5Bạn có thể nhận thấy lỗi này bật lên khi sử dụng
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
4, class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
5 và một số gói mã nguồn mở phổ biến khác. Điều đã xảy ra là các hàm bên trong đang bắt đầu sử dụng các kiểu trả về thích hợp. Nếu bạn đang mở rộng một lớp từ thư viện tiêu chuẩn [chẳng hạn như class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
6], bạn cũng sẽ cần thêm các loại trả về đóCách khắc phục rất đơn giản. cập nhật mã nhà cung cấp của bạn nếu xảy ra lỗi trong gói của bên thứ ba [hầu hết các lỗi đó đã được sửa với các bản phát hành mới nhất của họ]. Nếu xảy ra lỗi trong mã của bạn, bạn có thể thêm thuộc tính
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
7, khắc phục lỗi cho đến PHP 9. 0. Đây là một ví dụ về một lớp mở rộng class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
8class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
6Hoặc bạn chỉ cần thêm kiểu trả về
class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
7Hạn chế sử dụng class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
9 RFC
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
Một thay đổi nhỏ đối với cách sử dụng
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
9 sẽ có tác động đáng kể đến hiệu suất của tất cả các hoạt động mảng. Nikita làm tốt công việc giải thích vấn đề và giải pháp trong RFC. Thay đổi có nghĩa là một số trường hợp cạnh không thể thực hiện được nữa với class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
9. "Những gì không còn được hỗ trợ sẽ được ghi vào toàn bộ $GLOBALS. Tất cả những điều sau đây sẽ tạo ra lỗi thời gian biên dịch"class Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
8Ngoài ra, việc chuyển
class MyController {
public function __construct[
private Logger $logger = new NullLogger[],
] {}
}
9 theo tham chiếu sẽ tạo ra lỗi thời gian chạyclass Post
{
public function __construct[
private Status $status = Status::Pending;
] {}
public function setStatus[Status $status]: void
{
// …
}
}
$post->setStatus[Status::Active];
9Nikita đã phân tích 2000 gói hàng đầu trên Packagist và chỉ tìm thấy 23 trường hợp sẽ bị ảnh hưởng bởi thay đổi này. Chúng ta có thể kết luận rằng tác động của việc này — sự thay đổi về mặt kỹ thuật — sẽ thấp, đó là lý do tại sao nội bộ quyết định thêm nó vào PHP 8. 1. Hãy nhớ rằng hầu hết chúng ta sẽ giành chiến thắng nhờ sự thay đổi này, do tác động hiệu suất tích cực mà nó có ở mọi nơi trong mã của chúng ta
Tài nguyên để di chuyển đối tượng
Những thay đổi này là một phần của tầm nhìn dài hạn nhằm chuyển đổi tất cả các tài nguyên thành các đối tượng chuyên dụng. Bạn có thể đọc thêm về nó ở đây
Fileinfo chức năng với các đối tượng
class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
3Các chức năng như
class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
4 và class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
5 được sử dụng để chấp nhận và trả lại tài nguyên. Kể từ PHP 8. 1, họ làm việc với class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
3 đối tượngHàm IMAP với các đối tượng
class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
7Giống như thay đổi thông tin tệp, các chức năng IMAP như
class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
8 và class PostData {
public function __construct[
public readonly string $title,
public readonly DateTimeImmutable $date,
] {}
}
9 không còn hoạt động với các tài nguyênKhông dùng nữa việc chuyển null sang đối số không nullable của các hàm bên trong RFC
Sự thay đổi này đơn giản. các chức năng bên trong hiện chấp nhận
$post = new Post['Title', /* … */];
$post->title = 'Other';
Error: Cannot modify readonly property Post::$title
0 cho các đối số không thể vô hiệu, RFC này không chấp nhận hành vi đó. Ví dụ, điều này hiện có thể$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
0Trong PHP8. 1, các loại lỗi này sẽ đưa ra cảnh báo không dùng nữa, trong PHP 9, chúng sẽ được chuyển thành lỗi loại
Tự động hóa trên $post = new Post['Title', /* … */];
$post->title = 'Other';
Error: Cannot modify readonly property Post::$title
1 RFC
$post = new Post['Title', /* … */];
$post->title = 'Other';
Error: Cannot modify readonly property Post::$title
Từ RFC
PHP vốn cho phép tự động hóa [tự động tạo mảng từ các giá trị falsey]. Tính năng này rất hữu ích và được sử dụng trong rất nhiều dự án PHP, đặc biệt nếu biến không xác định. Tuy nhiên, có một chút kỳ lạ là cho phép tạo mảng từ giá trị false và null
Bạn có thể đọc chi tiết trên trang RFC. Tóm lại, hành vi này không được chấp nhận
$fiber = new Fiber[function []: void {
$valueAfterResuming = Fiber::suspend['after suspending'];
// …
}];
$valueAfterSuspending = $fiber->start[];
$fiber->resume['after resuming'];
1Những thay đổi nhỏ khác
Với mỗi bản phát hành, có một loạt các thay đổi rất nhỏ đối với ngôn ngữ. Tất cả chúng đều được liệt kê trong hướng dẫn NÂNG CẤP trên GitHub và RFC không dùng nữa, hãy đảm bảo kiểm tra nếu bạn muốn biết từng chi tiết nhỏ
Dưới đây là tóm tắt những thay đổi quan trọng nhất
2 không còn tác dụng$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
3 không còn tác dụng$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
- PDO. ATTR_STRINGIFY_FETCHESnow cũng hoạt động với booleans
- Số nguyên và số float trong tập kết quả PDO MySQL và Sqlite sẽ được trả về bằng cách sử dụng các kiểu PHP gốc thay vì chuỗi khi sử dụng các câu lệnh đã chuẩn bị được mô phỏng
- Các chức năng như
4 và$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
5 hiện cũng thoát khỏi$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
6 theo mặc định thành$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
7;$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
8,$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
9 và$post = new Post['Title', /* … */]; $post->title = 'Other'; Error: Cannot modify readonly property Post::$title
0 có thêm một đối số được gọi làfunction foo[int $a, int $b] { /* … */ } $foo = foo[...]; $foo[a: 1, b: 2];
1, nó có giá trị mặc định làfunction foo[int $a, int $b] { /* … */ } $foo = foo[...]; $foo[a: 1, b: 2];
2 nên nó sẽ không ảnh hưởng đến mã của bạnfunction foo[int $a, int $b] { /* … */ } $foo = foo[...]; $foo[a: 1, b: 2];
- Hỗ trợ mới cho
3 vàfunction foo[int $a, int $b] { /* … */ } $foo = foo[...]; $foo[a: 1, b: 2];
4function foo[int $a, int $b] { /* … */ } $foo = foo[...]; $foo[a: 1, b: 2];
Xây dựng một máy phát tia lửa điện
Tạm thời là vậy, hãy nhớ rằng tôi sẽ thường xuyên cập nhật bài đăng này trong năm, vì vậy hãy đảm bảo đăng ký nếu bạn muốn được cập nhật. Bạn có hào hứng với PHP 8 không. 1?
Nhận thấy một tpyo? . Nếu bạn muốn cập nhật những gì đang diễn ra trên blog này, bạn có thể theo dõi tôi trên Twitter hoặc đăng ký nhận bản tin của tôi. Đăng ký email