Hướng dẫn what are the new features in php 8? - các tính năng mới trong php 8 là gì?

Dễ dàng tối ưu hóa hiệu suất mã PHP trong sản xuất với Datadog APM. Cho phép các vấn đề về khả năng hiển thị và khắc phục sự cố nhanh hơn. Bắt đầu thử nghiệm miễn phí ngay hôm nay.

Show

Php 8 đã được phát hành vào ngày 26 tháng 11 năm 2020. Bạn có thể tải xuống tại đây. Đó là một phiên bản chính mới, có nghĩa là có một số thay đổi phá vỡ, cũng như rất nhiều tính năng mới và cải tiến hiệu suất.

Vì những thay đổi phá vỡ, có khả năng cao hơn bạn sẽ cần thực hiện một số thay đổi trong mã của mình để thực hiện nó trên Php 8. Nếu bạn luôn cập nhật các bản phát hành mới nhất, việc nâng cấp cũng không nên Khó, vì hầu hết các thay đổi phá vỡ đã được không phản đối trước đó trong các phiên bản 7.*. Và đừng lo lắng, tất cả những lời từ chối này được liệt kê trong bài đăng này.

Bên cạnh việc phá vỡ các thay đổi, PHP 8 cũng mang đến một bộ các tính năng mới đẹp như trình biên dịch JIT, các loại công đoàn, thuộc tính, v.v.

# Các tính năng mới

Hãy bắt đầu với tất cả các tính năng mới, nó khá là một danh sách!


# Liên minh các loại RFC

Với tính chất được đánh máy động của PHP, có rất nhiều trường hợp các loại liên minh có thể hữu ích. Các loại công đoàn là một tập hợp gồm hai hoặc nhiều loại chỉ ra rằng một trong hai loại có thể được sử dụng.

public function foo(Foo|Bar $input): int|float;

Lưu ý rằng

$dateAsString = $booking->getStartDate()?->asDateTimeString();
9 không bao giờ có thể là một phần của loại công đoàn, vì nó chỉ ra "hoàn toàn không có giá trị trả về". Hơn nữa, các công đoàn
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
0 có thể được viết bằng cách sử dụng
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
1 hoặc bằng cách sử dụng ký hiệu
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
2 hiện có:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;

# JIT RFC

JIT - chỉ trong thời gian - trình biên dịch hứa hẹn các cải tiến hiệu suất đáng kể, mặc dù không phải lúc nào cũng trong bối cảnh của các yêu cầu web. Tôi đã thực hiện các điểm chuẩn của riêng mình trên các ứng dụng web ngoài đời thực và có vẻ như JIT không tạo ra sự khác biệt nhiều, nếu có, trên các loại dự án PHP đó.

Nếu bạn muốn biết thêm về những gì JIT có thể làm cho PHP, bạn có thể đọc một bài viết khác tôi đã viết về nó ở đây.


# Nhà điều hành Nullsafe RFC

Nếu bạn quen thuộc với nhà điều hành Null Coalescing, bạn đã quen thuộc với những thiếu sót của nó: nó không hoạt động trên các cuộc gọi phương thức. Thay vào đó, bạn cần kiểm tra trung gian hoặc dựa vào người trợ giúp

function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
3 được cung cấp bởi một số khung:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;

Với việc bổ sung toán tử Nullsafe, giờ đây chúng ta có thể có hành vi giống như Null Coalescing trên các phương pháp!

$dateAsString = $booking->getStartDate()?->asDateTimeString();

Bạn có thể đọc tất cả về toán tử nullsafe ở đây.


# Đối số được đặt tên RFC

Các đối số được đặt tên cho phép bạn chuyển các giá trị vào một hàm, bằng cách chỉ định tên giá trị, để bạn không phải xem xét đặt hàng của chúng và bạn cũng có thể bỏ qua các tham số tùy chọn!

function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);

Bạn có thể đọc về chúng chuyên sâu trong bài viết này.


# Thuộc tính RFC

Các thuộc tính, thường được gọi là chú thích trong các ngôn ngữ khác, cung cấp một cách để thêm dữ liệu meta vào các lớp, mà không cần phải phân tích các docblocks.

Đối với một cái nhìn nhanh, đây là một ví dụ về các thuộc tính trông như thế nào, từ RFC:

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
#[Attribute]
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}

Lưu ý rằng cơ sở này

function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
4 được gọi là
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
5 trong RFC ban đầu, nhưng đã được thay đổi với một RFC khác sau đó. Nếu bạn muốn đi sâu vào cách các thuộc tính hoạt động và cách bạn có thể tự xây dựng; Bạn có thể đọc về các thuộc tính chuyên sâu trên blog này.

Nhận thấy một tpyo? Bạn có thể gửi PR để sửa nó. Nếu bạn muốn cập nhật những gì đang xảy 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:

# Match Biểu thức RFC

Bạn có thể gọi nó là Big Brother của biểu thức

function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
6:
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
7 có thể trả về các giá trị, không yêu cầu các câu lệnh
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
8, có thể kết hợp các điều kiện, sử dụng so sánh loại nghiêm ngặt và không thực hiện bất kỳ loại cưỡng chế nào.

Có vẻ như thế này:

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};

Bạn có thể đọc về biểu thức trận đấu một cách chi tiết, ở đây.


# Thuộc tính Constructor RFC

RFC này thêm đường cú pháp để tạo các đối tượng giá trị hoặc các đối tượng truyền dữ liệu. Thay vì chỉ định các thuộc tính lớp và hàm tạo cho chúng, giờ đây PHP hiện có thể kết hợp chúng thành một.

Thay vì làm điều này:

class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}

Bây giờ bạn có thể làm điều này:

class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}

Có rất nhiều điều để kể về khuyến mãi tài sản, bạn có thể đọc về chúng trong bài viết chuyên dụng này.


# MỚI function foo(string $a, string $b, ?string $c = null, ?string $d = null) { /* … */ } foo( b: 'value b', a: 'value a', d: 'value d', );9 RETURN LOẠI RFC

Mặc dù đã có thể trả lại

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
0,
function foo(string $a, string $b, ?string $c = null, ?string $d = null) 
{ /* … */ }

foo(
    b: 'value b', 
    a: 'value a', 
    d: 'value d',
);
9 không phải là loại trả lại hợp lệ cho đến khi PHP 8. Với bản chất được đánh máy động của PHP, nhưng đó là một tính năng sẽ hữu ích cho nhiều nhà phát triển.

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
0

# Mới use App\Attributes\ExampleAttribute; #[ExampleAttribute] class Foo { #[ExampleAttribute] public const FOO = 'foo'; #[ExampleAttribute] public $x; #[ExampleAttribute] public function foo(#[ExampleAttribute] $bar) { } }2 Loại RFC

Một số người có thể gọi nó là một điều ác cần thiết: loại

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
2 khiến nhiều người có cảm xúc lẫn lộn. Có một lập luận rất tốt để đưa ra cho nó: một loại thiếu có thể có nghĩa là rất nhiều thứ trong PHP:

  • Một chức năng không trả về không có gì hoặc null
  • Chúng tôi đang mong đợi một trong nhiều loại
  • Chúng tôi đang mong đợi một loại không thể loại được gợi ý trong PHP

Vì những lý do trên, đó là một điều tốt mà loại

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
2 được thêm vào.
use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
2 có nghĩa là một trong những loại sau:

  • use App\Attributes\ExampleAttribute;
    
    #[ExampleAttribute]
    class Foo
    {
        #[ExampleAttribute]
        public const FOO = 'foo';
     
        #[ExampleAttribute]
        public $x;
     
        #[ExampleAttribute]
        public function foo(#[ExampleAttribute] $bar) { }
    }
    6
  • use App\Attributes\ExampleAttribute;
    
    #[ExampleAttribute]
    class Foo
    {
        #[ExampleAttribute]
        public const FOO = 'foo';
     
        #[ExampleAttribute]
        public $x;
     
        #[ExampleAttribute]
        public function foo(#[ExampleAttribute] $bar) { }
    }
    7
  • use App\Attributes\ExampleAttribute;
    
    #[ExampleAttribute]
    class Foo
    {
        #[ExampleAttribute]
        public const FOO = 'foo';
     
        #[ExampleAttribute]
        public $x;
     
        #[ExampleAttribute]
        public function foo(#[ExampleAttribute] $bar) { }
    }
    8
  • use App\Attributes\ExampleAttribute;
    
    #[ExampleAttribute]
    class Foo
    {
        #[ExampleAttribute]
        public const FOO = 'foo';
     
        #[ExampleAttribute]
        public $x;
     
        #[ExampleAttribute]
        public function foo(#[ExampleAttribute] $bar) { }
    }
    9
  • #[Attribute]
    class ExampleAttribute
    {
        public $value;
     
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    0
  • #[Attribute]
    class ExampleAttribute
    {
        public $value;
     
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    1
  • #[Attribute]
    class ExampleAttribute
    {
        public $value;
     
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    2
  • #[Attribute]
    class ExampleAttribute
    {
        public $value;
     
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    3
  • #[Attribute]
    class ExampleAttribute
    {
        public $value;
     
        public function __construct($value)
        {
            $this->value = $value;
        }
    }
    4

Lưu ý rằng

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
2 cũng có thể được sử dụng làm tham số hoặc loại thuộc tính, không chỉ là loại trả về.

Cũng lưu ý rằng vì

use App\Attributes\ExampleAttribute;

#[ExampleAttribute]
class Foo
{
    #[ExampleAttribute]
    public const FOO = 'foo';
 
    #[ExampleAttribute]
    public $x;
 
    #[ExampleAttribute]
    public function foo(#[ExampleAttribute] $bar) { }
}
2 đã bao gồm
#[Attribute]
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}
1, nên nó không được phép làm cho nó không thể đạt được. Điều sau đây sẽ kích hoạt lỗi:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
1

# Ném biểu thức RFC

RFC này thay đổi

#[Attribute]
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}
8 từ việc trở thành một tuyên bố thành một biểu thức, điều này có thể ném ngoại lệ ở nhiều nơi mới:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
2

# Kế thừa với các phương thức riêng tư RFC

Trước đây, PHP được sử dụng để áp dụng các kiểm tra kế thừa tương tự trên các phương thức công khai, được bảo vệ và riêng tư. Nói cách khác: Các phương thức riêng tư nên tuân theo các quy tắc chữ ký phương thức tương tự như các phương thức được bảo vệ và công khai. Điều này không có ý nghĩa, vì các phương thức riêng tư sẽ không thể truy cập được bởi các lớp trẻ em.

RFC này đã thay đổi hành vi đó, để các kiểm tra kế thừa này không được thực hiện trên các phương thức riêng tư nữa. Hơn nữa, việc sử dụng

#[Attribute]
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}
9 cũng không có ý nghĩa, vì vậy làm như vậy bây giờ sẽ kích hoạt cảnh báo:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
3

# Bản đồ yếu RFC

Được xây dựng dựa trên RFC yếu được thêm vào Php 7.4, việc triển khai

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
0 được thêm vào trong Php 8.
$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
0 giữ các tham chiếu đến các đối tượng, không ngăn chặn các đối tượng đó được thu thập.

Lấy ví dụ về Orms, họ thường thực hiện bộ nhớ cache tổ chức tham chiếu đến các lớp thực thể để cải thiện hiệu suất của mối quan hệ giữa các thực thể. Các đối tượng thực thể này không thể được thu thập rác, miễn là bộ đệm này có liên quan đến chúng, ngay cả khi bộ đệm là thứ duy nhất tham khảo chúng.

Nếu lớp bộ nhớ đệm này sử dụng các tài liệu tham khảo và bản đồ yếu thay thế, PHP sẽ rác thu thập các đối tượng này khi không còn gì khác tham khảo chúng nữa. Đặc biệt là trong trường hợp của Orms, có thể quản lý hàng trăm hàng trăm, nếu không phải hàng ngàn thực thể trong một yêu cầu; Bản đồ yếu có thể cung cấp một cách đối phó tốt hơn, thân thiện hơn với các đối tượng này.

Đây là những bản đồ yếu trông như thế nào, một ví dụ từ RFC:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
4

# Cho phép $result = match($input) { 0 => "hello", '1', '2', '3' => "world", };2 trên các đối tượng RFC

Một tính năng mới, nhưng hữu ích, mới: Bây giờ có thể sử dụng

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
2 trên các đối tượng, thay vì phải sử dụng
$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
4 trên chúng. Nó hoạt động theo cách tương tự như
$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
4.

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
5

# Bắt không bắt giữ RFC

Bất cứ khi nào bạn muốn bắt một ngoại lệ trước Php 8, bạn phải lưu trữ nó trong một biến, bất kể bạn có sử dụng biến đó hay không. Với các sản phẩm khai thác không bắt giữ, bạn có thể bỏ qua biến, vì vậy thay vì điều này:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
6

Bây giờ bạn có thể làm điều này:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
7

Lưu ý rằng nó được yêu cầu luôn chỉ định loại, bạn không được phép có một

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
6 trống. Nếu bạn muốn bắt tất cả các ngoại lệ và lỗi, bạn có thể sử dụng
$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
7 làm loại bắt.


# Dấu phẩy trong danh sách tham số RFC

Đã có thể khi gọi một chức năng, hỗ trợ dấu phẩy kéo dài vẫn còn thiếu trong danh sách tham số. Bây giờ nó được phép trong Php 8, có nghĩa là bạn có thể làm như sau:

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
8

Là một sidenote: dấu phẩy kéo dài cũng được hỗ trợ trong danh sách đóng cửa

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
8, đây là một sự giám sát và hiện được thêm vào thông qua một RFC riêng biệt.


# Tạo đối tượng $result = match($input) { 0 => "hello", '1', '2', '3' => "world", };9 từ giao diện

Bạn đã có thể tạo một đối tượng

$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
9 từ đối tượng
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
1 bằng cách sử dụng
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
2, nhưng cách khác là khó khăn. Bằng cách thêm
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
3 và
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
4 hiện có một cách tổng quát để chuyển đổi các đối tượng
$result = match($input) {
    0 => "hello",
    '1', '2', '3' => "world",
};
9 và
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
1 cho nhau.

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
9

# Giao diện class Money { public Currency $currency; public int $amount; public function __construct( Currency $currency, int $amount, ) { $this->currency = $currency; $this->amount = $amount; } }7 mới RFC

Giao diện

class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
7 có thể được sử dụng để gõ gợi ý bất cứ điều gì thực hiện
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
9. Bất cứ khi nào một lớp thực hiện
class Money 
{
    public Currency $currency;
 
    public int $amount;
 
    public function __construct(
        Currency $currency,
        int $amount,
    ) {
        $this->currency = $currency;
        $this->amount = $amount;
    }
}
9, nó sẽ tự động thực hiện giao diện phía sau hậu trường và không cần phải thực hiện thủ công nó.

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
0

# Mới class Money { public function __construct( public Currency $currency, public int $amount, ) {} }1 chức năng RFC

Một số người có thể nói rằng nó đã quá hạn lâu, nhưng cuối cùng chúng tôi không phải dựa vào

class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}
2 nữa để biết liệu một chuỗi có chứa một chuỗi khác hay không.

Thay vì làm điều này:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
1

Bây giờ bạn có thể làm điều này

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
2

# Mới class Money { public function __construct( public Currency $currency, public int $amount, ) {} }3 và class Money { public function __construct( public Currency $currency, public int $amount, ) {} }4 Chức năng RFC

Hai cái khác quá hạn lâu, hai chức năng này hiện được thêm vào cốt lõi.

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
3

# Hàm class Money { public function __construct( public Currency $currency, public int $amount, ) {} }5 mới

Hàm

class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}
5 mới thực hiện một cái gì đó tương tự như các hàm
class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}
7 và
class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}
8, cho phép phân chia theo 0. Thay vì các lỗi, bạn sẽ nhận được
class Money 
{
    public function __construct(
        public Currency $currency,
        public int $amount,
    ) {}
}
9,
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
00 hoặc
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
01, tùy thuộc vào trường hợp.


# Mới public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;02 RFC chức năng

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
02 Trả về loại biến. Nghe có vẻ như
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
04 sẽ làm?
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
02 Trả về đầu ra hữu ích hơn cho các mảng, chuỗi, các lớp và đối tượng ẩn danh.

Ví dụ: gọi

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
04 trên lớp
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
07 sẽ trả về
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
08. Sử dụng
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
02 sẽ trả về tên lớp.

Một danh sách đầy đủ các khác biệt giữa

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
02 và
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
04 có thể được tìm thấy trong RFC.


# Hàm public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;12 mới

Tài nguyên là các biến đặc biệt trong PHP, đề cập đến các tài nguyên bên ngoài. Một ví dụ là kết nối MySQL, một xử lý tệp khác.

Mỗi một trong số các tài nguyên đó được gán một ID, mặc dù trước đây là cách duy nhất để biết rằng ID là chuyển tài nguyên lên

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
13:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
4

Php 8 thêm các chức năng

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
12, làm cho hoạt động này rõ ràng và an toàn hơn:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
5

# Phương pháp trừu tượng trong các đặc điểm cải tiến RFC

Các đặc điểm có thể chỉ định các phương thức trừu tượng phải được thực hiện bởi các lớp bằng cách sử dụng chúng. Mặc dù vậy, có một cảnh báo: Trước Php 8, chữ ký của các phương pháp này không được xác thực. Điều sau đây là hợp lệ:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
6

Php 8 sẽ thực hiện xác thực chữ ký phương pháp thích hợp khi sử dụng một đặc điểm và thực hiện các phương thức trừu tượng của nó. Điều này có nghĩa là bạn sẽ cần phải viết cái này thay thế:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
7

# Thực hiện đối tượng của public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;15 RFC

Hàm

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
15 trả về một mảng các giá trị. RFC này thêm một lớp
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
17 với phương thức
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
18. Việc triển khai này hoạt động với các đối tượng thay vì các giá trị đơn giản. Nó tiêu thụ ít bộ nhớ hơn và dễ đọc hơn.


# Điều chỉnh cú pháp biến đổi RFC

Từ RFC: "Cú pháp biến đồng đều RFC đã giải quyết một số điểm không nhất quán trong cú pháp biến của PHP. RFC này dự định sẽ giải quyết một số ít các trường hợp bị bỏ qua."


# Nhập chú thích cho các chức năng nội bộ bên ngoài

Rất nhiều người đã tham gia để thêm các chú thích loại thích hợp cho tất cả các chức năng nội bộ. Đây là một vấn đề lâu dài, và cuối cùng có thể giải quyết được tất cả các thay đổi được thực hiện cho PHP trong các phiên bản trước. Điều này có nghĩa là các chức năng và phương pháp nội bộ sẽ có thông tin loại đầy đủ trong phản ánh.


# public function foo(Foo|null $foo): void; public function bar(?Bar $bar): void;19 luôn có sẵn RFC

Trước đây có thể biên dịch PHP mà không có tiện ích mở rộng JSON được bật, điều này là không thể nữa. Vì JSON được sử dụng rộng rãi, nên các nhà phát triển tốt nhất luôn có thể phụ thuộc vào nó ở đó, thay vì phải đảm bảo phần mở rộng tồn tại trước tiên.

# Phá vỡ thay đổi

Như đã đề cập trước đây: Đây là một bản cập nhật lớn và do đó sẽ có những thay đổi phá vỡ. Điều tốt nhất để làm là hãy xem danh sách đầy đủ các thay đổi phá vỡ tại tài liệu nâng cấp.

Mặc dù vậy, nhiều trong số những thay đổi phá vỡ này đã bị phản đối trong các phiên bản 7.* trước đây, vì vậy nếu bạn đã luôn cập nhật qua nhiều năm, thì không nên nâng cấp lên Php 8.

# Lỗi loại nhất quán RFC

Các chức năng do người dùng xác định trong PHP sẽ ném

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
20, nhưng các chức năng nội bộ thì không, họ đã phát ra cảnh báo và trả về
#[Attribute]
class ExampleAttribute
{
    public $value;
 
    public function __construct($value)
    {
        $this->value = $value;
    }
}
1. Theo Php 8, hành vi của các chức năng nội bộ đã được thực hiện nhất quán.


# Cảnh báo động cơ được phân loại lại RFC

Rất nhiều lỗi mà trước đây chỉ kích hoạt các cảnh báo hoặc thông báo, đã được chuyển đổi thành các lỗi thích hợp. Các cảnh báo sau đây đã được thay đổi.

  • Biến không xác định: Cảnh báo thay vì thông báo
  • Chỉ số mảng không xác định: Cảnh báo thay vì thông báo
  • Phân chia theo 0:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    22 Ngoại lệ thay vì cảnh báo
  • Cố gắng tăng/giảm thuộc tính '%s' của đối tượng:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Cố gắng sửa đổi thuộc tính '%s' của không đối tượng:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Cố gắng gán tài sản '%s' của đối tượng không đối tượng:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Tạo đối tượng mặc định từ giá trị trống:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 Ngoại lệ thay vì cảnh báo
  • Cố gắng lấy tài sản '%s' của đối tượng: cảnh báo thay vì thông báo
  • Tài sản không xác định: %s :: %s: cảnh báo thay vì thông báo
  • Không thể thêm phần tử vào mảng vì phần tử tiếp theo đã bị chiếm:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Không thể giải quyết bù trong một biến không phải là một biến:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Không thể sử dụng giá trị vô hướng làm mảng:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Chỉ có thể giải nén các mảng và
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    30:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 ngoại lệ thay vì cảnh báo
  • Đối số không hợp lệ được cung cấp cho foreach ():
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 Ngoại lệ thay vì cảnh báo
  • Loại bù bất hợp pháp:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 Ngoại lệ thay vì cảnh báo
  • Loại bù bất hợp pháp trong ISSET hoặc trống:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 Ngoại lệ thay vì cảnh báo
  • Loại bù bất hợp pháp trong Untet:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 Ngoại lệ thay vì cảnh báo
  • Mảng sang chuyển đổi chuỗi: Cảnh báo thay vì thông báo
  • ID tài nguyên#%d được sử dụng làm bù, đúc vào số nguyên (%d): cảnh báo thay vì thông báo
  • Xảy ra diễn viên bù chuỗi: cảnh báo thay vì thông báo
  • Chuỗi không đơn vị bù: %d: cảnh báo thay vì thông báo
  • Không thể gán một chuỗi trống cho một chuỗi bù:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    23 ngoại lệ thay vì cảnh báo
  • Tài nguyên được cung cấp không phải là tài nguyên luồng hợp lệ:
    public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    20 Ngoại lệ thay vì cảnh báo

# Nhà điều hành @ không còn làm im lặng các lỗi gây tử vong

Có thể thay đổi này có thể tiết lộ các lỗi mà một lần nữa bị ẩn trước PHP 8. Hãy đảm bảo đặt

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
38 trên máy chủ sản xuất của bạn!


# Cấp độ báo cáo lỗi mặc định

Bây giờ là

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
39 thay vì tất cả mọi thứ trừ
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
40 và
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
41. Điều này có nghĩa là nhiều lỗi có thể bật lên mà trước đây âm thầm bị bỏ qua, mặc dù có lẽ đã tồn tại trước PHP 8.


# Chế độ lỗi PDO mặc định RFC

Từ RFC: Chế độ lỗi mặc định hiện tại cho PDO là im lặng. Điều này có nghĩa là khi xảy ra lỗi SQL, không có lỗi hoặc cảnh báo nào có thể được phát ra và không có ngoại lệ nào được ném trừ khi nhà phát triển thực hiện xử lý lỗi rõ ràng của chính họ.

RFC này thay đổi lỗi mặc định sẽ thay đổi thành

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
42 trong Php 8.


# Concatenation ưu tiên RFC

Mặc dù đã không được dùng trong Php 7.4, nhưng sự thay đổi này hiện được thực hiện. Nếu bạn viết một cái gì đó như thế này:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
8

PHP trước đây sẽ giải thích nó như thế này:

$startDate = $booking->getStartDate();

$dateAsString = $startDate ? $startDate->asDateTimeString() : null;
9

Php 8 sẽ làm cho nó được giải thích như thế này:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
0

# Kiểm tra loại nghiêm ngặt hơn cho các toán tử số học và bitwise RFC

Trước Php 8, có thể áp dụng các toán tử số học hoặc bitwise trên các mảng, tài nguyên hoặc đối tượng. Điều này không thể nữa, và sẽ ném

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
43:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
1

# Tên được đặt tên là một mã thông báo duy nhất RFC

PHP được sử dụng để giải thích từng phần của không gian tên (được phân tách bằng dấu gạch chéo ngược

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
44) như một chuỗi các mã thông báo. RFC này đã thay đổi hành vi đó, có nghĩa là tên dành riêng hiện có thể được sử dụng trong các không gian tên.


# Chuỗi số saner rfc

Hệ thống loại của PHP cố gắng làm rất nhiều việc thông minh khi nó gặp các số trong chuỗi. RFC này làm cho hành vi đó nhất quán và rõ ràng hơn.


# Chuỗi saner để so sánh số RFC

RFC này sửa chữa trường hợp rất lạ trong PHP trong đó

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
45 dẫn đến
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
46. Có một số trường hợp cạnh khác như thế, và RFC này sửa chúng.


# Thay đổi phản xạ

Một vài phương pháp phản ánh đã bị phản đối:

  • public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    47
  • public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    48
  • public function foo(Foo|null $foo): void;
    
    public function bar(?Bar $bar): void;
    49

Bây giờ bạn nên sử dụng

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
50 để lấy thông tin về loại tham số:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
2

Nếu loại là một loại duy nhất,

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
51 sẽ trả về một thể hiện là
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
52, bạn có thể lấy tên của nó từ và liệu nó có được tích hợp không: liệu nó có được tích hợp không:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
3

Tuy nhiên, nếu loại là loại liên minh, bạn sẽ nhận được một thể hiện là

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
53, có thể cung cấp cho bạn một mảng
public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
52 như vậy:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
4

Kiểm tra xem một loại có phải là liên minh hay không có thể được thực hiện với kiểm tra

public function foo(Foo|null $foo): void;

public function bar(?Bar $bar): void;
55:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
5

Tiếp theo, ba chữ ký phương pháp của các lớp phản xạ đã được thay đổi:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
6

Bây giờ đã trở thành:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
7

Hướng dẫn nâng cấp chỉ định rằng nếu bạn mở rộng các lớp này và vẫn muốn hỗ trợ cả Php 7 và Php 8, các chữ ký sau đây được cho phép:

$dateAsString = $booking->getStartDate()?->asDateTimeString();
8

# Sắp xếp ổn định RFC

Trước PHP 8, các thuật toán sắp xếp không ổn định. Điều này có nghĩa là thứ tự của các yếu tố bằng nhau không được đảm bảo. Php 8 thay đổi hành vi của tất cả các chức năng sắp xếp thành phân loại ổn định.


# Lỗi nghiêm trọng đối với chữ ký phương pháp không tương thích RFC

Từ RFC: Lỗi kế thừa do chữ ký phương pháp không tương thích hiện đang ném lỗi nghiêm trọng hoặc cảnh báo tùy thuộc vào nguyên nhân của lỗi và hệ thống phân cấp kế thừa.


# Khv việc và thay đổi khác

Trong quá trình phát triển PHP 7.*, một số khấu hao đã được thêm vào hiện được hoàn thành trong PHP 8.

  • Khấu hao trong Php 7.2
  • Khấu hao trong Php 7.3
  • Khấu hao trong Php 7.4
  • Phao Float độc lập địa phương đến Chuỗi Cast

Nhận thấy một tpyo? Bạn có thể gửi PR để sửa nó. Nếu bạn muốn cập nhật những gì đang xảy 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:

Chú thích

Có gì mới trong Php 8.2

Có gì mới trong Php 8.1

Nâng cấp lên Php 8 bằng Homebrew trên máy Mac

Toán tử nullsafe

Toán tử phù hợp trong PHP 8

Các đối số được đặt tên trong Php 8

Khuyến mãi tài sản trong Php 8

Phiên bản PHP mới nhất - Cách quản lý Php hiện đại

Các thuộc tính trong Php 8 - Một cái nhìn cận cảnh về các thuộc tính, còn được gọi là chú thích

PHP năm 2020

Có gì mới trong Php 7.4

Có gì mới trong Php 7.3

Phiên bản mới nhất của PHP 8 là gì?

Php 8.2 là phiên bản PHP lớn sắp tới, sẽ được phát hành vào tháng 11 năm 2022. is the upcoming major PHP version, to be released on November 2022.

Sự khác biệt giữa PHP 7.4 và 8 là gì?

Q. Sự khác biệt giữa Php 7.4 và 8 là gì?Trả lời: Một trong nhiều ví dụ là, WordPress trên Php 8.0 có thể xử lý nhiều yêu cầu hơn 18,4% mỗi giây so với Php 7.4.Hơn nữa, Laravel trên PHP 8.0 có thể chạy thêm 8,5% yêu cầu mỗi giây so với Php 7.3.WordPress on PHP 8.0 can handle 18.4% more requests per second than PHP 7.4. Moreover, Laravel on PHP 8.0 can run 8.5% more requests per second than PHP 7.3.

Tại sao PHP 8 nhanh hơn?

Php 8 sẽ nhanh hơn nhiều so với Php 7 vì trình biên dịch JIT không đồng bộ và JIT mới, bạn sẽ có thể xây dựng các ứng dụng không đồng bộ trong Php 8, đây là một vấn đề lớn cho các trang web.because of the new asynchronous design and JIT compiler, you will be able to build asynchronous applications in PHP 8 which is a big deal for websites.

Có đáng để nâng cấp lên Php 8 không?

Lý do lớn nhất để chuyển sang Php 8 trước tháng 11 năm 2022 là vì sự hỗ trợ của cộng đồng cho Php 7.4 đang kết thúc.Nhưng nó không chỉ là về việc di chuyển các phiên bản không cần thiết - Php 8 mang lại những lợi ích với nó.PHP 8 brings bags of benefits with it.