PHP phiên bản 8 đã chính thức được phát hành vào hôm 26/11/2020. Vì nó là major version nên sẽ có nhiều thay đổi có thể dẫn đến việc update từ PHP phiên bản củ gây ra một số vấn đề. Ngoài ra nó cũng có nhiều tính năng mới, cải tiến, ... Bài viết này sẽ tóm tắt một số thay đổi chính đó.
Bạn cũng có thể tham khảo những thay đổi ở PHP 7.x tại đây

Constructor với property

class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}
}

Tham số với tên

class Point {
  public function __construct(
    public float $x = 0.0,
    public float $y = 0.0,
    public float $z = 0.0,
  ) {}
  
  public function move(float $dx, float $dy = 0.0, float $dz = 0.0): void
  {
    // logic
  }
}

$pz = new Point(z: 1);
$pzx = new Point(z: 1, x: 1);
$pzx->move(1, dz: 1);

Toán tử nullsafe ?

// Pre PHP 8
$country =  null;
if ($session !== null) {
  $user = $session->user;
  if ($user !== null) {
    $address = $user->getAddress();
    if ($address !== null) {
      $country = $address->country;
    }
  }
}

// PHP 8.0
$country = $session?->user?->getAddress()?->country;

Biểu thức match

match tương tự như switch nhưng:

match switch
biểu thức (expression) mệnh đề (statement)
sử dụng === để so sánh sử dụng == để so sánh
không cần break
chỉ được sử dụng 1 dòng ở mỗi match
function test_match($x): string
{
    return match($x) {
        '7.0', '7.1', '7.2', '7.3', '7.4' => "7x",
        '8.0' => "Oh no!",
        8.0 => "This is what I expected",
    };
}

echo test_match(8.0); // This is what I expected
echo test_match(7.0); // Uncaught UnhandledMatchError

Ngoài ra điều kiện của match có thể là một biểu thức bất kỳ

function rely($x)
{
    print("execute with $x, ");
    return $x;
}

function test_match($x)
{
    return match($x) {
        rely('8.0') => print('string, '),
        rely(8.0) => print('number, '),
    };
}

test_match(8.0); // execute with 8.0, execute with 8, number, 
test_match('8.0'); // execute with 8.0, string, 

Tất nhiên match vẫn có thể dùng điều kiện default

$size = 10;
echo match (true) {
    $size < 5 => 'small',
    $size >= 5 && $size < 8 => 'medium',
    default => 'large',
};
// large

Cải thiện phép so sánh ==

Trước PHP 8 phép == khi gặp number hoặc numeric string thì các toán hạng sẽ được chuyển sang number trước khi so sánh. Vì vậy dẫn đến một số kết quả không như mong muốn:

Comparison Pre PHP 8 PHP 8
0 == "0" true true
0 == "0.0" true true
0 == "foo" true false
0 == "" true false
42 == " 42" true true
42 == "42foo" true false

Kiểu Union

function foo(int|float $x) {}

foo('123'); // OK
foo('NaN'); // Uncaught TypeError

Attributes

Attributes cho phép ta định nghĩa thêm thông tin bổ sung cho class, funtion, method,... Sau đó sử dụng Reflection để lấy những thông tin đó.

#[Attribute]
class MyAttribute
{
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }
}

#[MyAttribute(value: 1234)]
class Thing
{
}

function dumpMyAttributeData($reflection) {
    $attributes = $reflection->getAttributes(MyAttribute::class);

    foreach ($attributes as $attribute) {
       var_dump($attribute->getName());
       var_dump($attribute->getArguments());
       var_dump($attribute->newInstance());
    }
}

dumpAttributeData(new ReflectionClass(Thing::class));
/*
string(11) "MyAttribute"
array(1) {
  ["value"]=>
  int(1234)
}
object(MyAttribute)#3 (1) {
  ["value"]=>
  int(1234)
}
*/

Just-In-Time compilation

Tại sao JIT lại giúp PHP nhanh hơn?

Nói 1 cách dễ hiểu thì:

PHP là ngôn ngữ không có bước compile code để chạy mà chạy trưc tiếp từ code luôn. Bản chất thì nó vẫn được compile lúc chạy. Vậy nó vẫn tốn thời gian compile lúc chạy dù rất là nhỏ nhưng vẫn chậm hơn khá nhiều do với mã đã được compile. JIT sẽ cache những đoạn compiled code được dùng nhiều vì thế sẽ đỡ tốn thời gian compile lại nên giúp thời gian thực thi nhanh hơn.

Cache thì cần bộ nhớ => cái này đc quyết định bởi opcache.jit_buffer_size

Cái gì được cache thì được quyết định bởi opcache.jit

Ví dụ để enable JIT

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=32M
opcache.jit=1235

Tham khảo