Những tính năng mới trong PHP 8.0
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