2020年12月4日

PHP | PHP 8.0 正式釋出 | 新功能簡單試玩

自從2015年底,PHP發布7.0.0後,歷經了將近五年的時間,PHP官方終於正式在2020.11.26發佈了PHP 8.0.0的版本。

這次的升級,如同官方所宣稱的,在執行效能上會更加快速、語法更為簡潔、而在型別的使用上也更加的安全。

版本的細節可以參考PHP官方網站:PHP 8 Released!

至於Laravel,是否完全支援PHP 8.0,根據這篇文章:Laravel: PHP 8 Support,Laravel 6、7、8都將支援 PHP 8,只是看起來還有一些套件需要調整,不過相信也不會太久,Laravel就可以完全享受到PHP 8.0帶來的好處了。

PHP 8.1 在 2021 年 11 月底釋出了,有興趣者可以前往這邊觀看。

PHP 8.0 特點介紹

以下我簡單試玩了一下官方重點宣傳,並且我比較感興趣的幾個特點。

Named arguments - 傳入的引數可以有名字了!

function createStudent($name, $gender = 'UNKNOWN', $age = null)
{
    echo "name: $name, gender: $gender, age: $age".PHP_EOL;
}

createStudent('Wendy', gender: 'girl');
// [1] output: name: Wendy, gender: girl, age:

createStudent('Eddie', age: '15');
// [2] output: name: Eddie, gender: UNKNOWN, age: 15

createStudent(age: 'girl', name: 'Lisa', gender: '20');
// [3] output: name: Lisa, gender: 20, age: girl
  
createStudent(age: 'girl', 'Lisa', gender: '20');
// [4] output: PHP Fatal error:  Cannot use positional argument after named argument
  • 有預設值的話,順序可以改變(範例2)
  • 所有參數都用Named arguments的方式傳入的話,不管有沒有預設值,都可以任意改變順序(範例3)
  • Named arguments之後,只能是Named arguments(範例4)

Cnstructor property promotion - 懶得宣告property者的救星

class Student{
  public function __construct(
    public $name = '',
    public $gender = 'UNKNOWN',
    public $age = null,
    private $grade = null,
  ) {
  }
}

$student = new Student(age: 20);
print_r($student);

output:

Student Object
(
    [name] =>
    [gender] => UNKNOWN
    [age] => 20
    [grade:Student:private] =>
)

可以直接在construct宣告類別的property了,真是懶人的救星。而且還可以搭配Named arguments使用。

Union types - 沒有理由不定義參數型別了

function setGrade(int|string $grade)
{
}

setGrade(1);
// int ok

setGrade('A');
// string ok

setGrade([]);
// PHP Fatal error:  Uncaught TypeError: setGrade(): Argument #1 ($grade) must be of type string|int, array given

以前還可以找藉口說傳入的參數型別可能會不一樣,為了彈性不要把型別定義的這麼死,這下總沒有理由了吧?通通union起來呀!

Match expression - 蛻變的switch

$currency = 'TWD';

$symbol = match ($currency) {
    'USD' => "US$",
    'TWD' => "NT$",
    'JPY' => "¥",
};

echo $symbol;

以前這種列舉式的轉換,經常需要寫很長的switch或if-else,現在靠match,就可以做到了,而且更精簡、更容易理解。

Nullsafe operator - 隨你串!更彈性的method chaining

class Home
{
    function __construct(
        public string $address
    ) {}
}

class Student
{
    function __construct(
        public ?Home $home = null
    ) {}
}

function getStudentHomeAddress(Student|null $student)
{
    return $student?->home?->address;
}

echo getStudentHomeAddress(null);
// null
echo getStudentHomeAddress(new Student());
// null
echo getStudentHomeAddress(new Student(new Home('Central of the World')));
// Central of the World

以往要串連多個物件,總是要不斷地確認物件是否為null,否則會一直得到惱人的warning: Attempt to read property xxx on null,有了Nullsafe operator後,可以讓程式碼中大量減少一下必要但重複性質高的判斷,讓程式碼看起來更簡潔。

Just-In-Time compilation(JIT) - PHP加速器

PHP 8 最受矚目的功能大概就是JIT了,自從PHP 5.5內建OPache以來,PHP可能又將迎來下一次的效能躍進。當然,目前實際上的效能提升還有待確認,但總體而言還是令人相當振奮的。

結論

雖然這次的升級非常令人振奮,但是不建議在正式環境產品或穩定的產品上使用,要再多觀察一陣子才行。(比較保守的人大概等到8.1以後吧?)

 

PHP 8.1 在 2021 年 11 月底釋出了,有興趣者可以前往這邊觀看。