2024 年 PHP Conference Japan
已發佈!
PHP 8.0 是 PHP 語言的主要更新。
它包含許多新功能和最佳化,包括具名引數、聯集類型、屬性、建構子屬性提升、匹配運算式、Nullsafe 運算子、JIT,以及類型系統、錯誤處理和一致性方面的改進。

具名引數 RFC

PHP 7
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
PHP 8
htmlspecialchars($string, double_encode: false);
  • 僅指定必要的參數,省略可選參數。
  • 參數的順序不重要,並且具備自文件性。

屬性 RFC 文件

PHP 7
class PostsController
{
/**
* @Route("/api/posts/{id}", methods={"GET"})
*/
public function get($id) { /* ... */ }
}
PHP 8
class PostsController
{
#[
Route("/api/posts/{id}", methods: ["GET"])]
public function
get($id) { /* ... */ }
}

現在可以使用 PHP 原生語法來使用結構化中繼資料,而不是 PHPDoc 註釋。

建構子屬性提升 RFC 文件

PHP 7
class Point {
public
float $x;
public
float $y;
public
float $z;

public function
__construct(
float $x = 0.0,
float $y = 0.0,
float $z = 0.0
) {
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
}
PHP 8
class Point {
public function
__construct(
public
float $x = 0.0,
public
float $y = 0.0,
public
float $z = 0.0,
) {}
}

更少的樣板程式碼來定義和初始化屬性。

聯合類型 RFC 文件

PHP 7
類別 Number {
/** @var int|float */
私有 $number;

/**
* @param float|int $number
*/
公開 function __construct($number) {
$this->number = $number;
}
}

new
Number('NaN'); // 可以
PHP 8
類別 Number {
公開 function
__construct(
私有
int|float $number
) {}
}

new
Number('NaN'); // 型別錯誤

您可以使用在執行階段驗證的原生聯集類型宣告,而不是使用 PHPDoc 註釋來組合類型。

Match 運算式 RFC 文件

PHP 7
switch (8.0) {
case
'8.0':
$result = "糟糕!";
break;
case
8.0:
$result = "這就是我預期的";
break;
}
echo
$result;
//> 糟糕!
PHP 8
echo match (8.0) {
'8.0' => "糟糕!",
8.0 => "這就是我預期的",
};
//> 這就是我預期的

新的 match 類似於 switch,並具有以下特性

  • Match 是一個運算式,表示其結果可以儲存在變數中或被返回。
  • Match 分支僅支援單行運算式,且不需要 break; 陳述式。
  • Match 會執行嚴格比較。

Nullsafe 運算子 RFC

PHP 7
$country = null;

if (
$session !== null) {
$user = $session->user;

if (
$user !== null) {
$address = $user->getAddress();

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

現在可以使用新的 nullsafe 運算子進行一連串的呼叫,而不必再進行 null 值檢查。當鏈中其中一個元素的評估失敗時,整個鏈的執行就會中止,且整個鏈的評估結果為 null。

更合理的字串與數字比較 RFC

PHP 7
0 == 'foobar' // true
PHP 8
0 == 'foobar' // false

當與數字字串比較時,PHP 8 會使用數字比較。否則,它會將數字轉換為字串,然後使用字串比較。

內建函式的一致性類型錯誤 RFC

PHP 7
strlen([]); // 警告:strlen() 預期參數 1 為字串,給定陣列

array_chunk([], -1); // 警告:array_chunk():大小參數應大於 0
PHP 8
strlen([]); // TypeError:strlen():參數 #1 ($str) 必須是字串類型,給定陣列

array_chunk([], -1); // ValueError:array_chunk():參數 #2 ($length) 必須大於 0

現在,如果參數驗證失敗,大多數內建函式都會拋出錯誤例外。

即時編譯 (JIT)

PHP 8 引入了兩個 JIT 編譯引擎。其中最有潛力的 Tracing JIT 在合成基準測試中顯示出大約 3 倍的效能提升,在某些特定的長時間運行應用程式中則有 1.5 到 2 倍的效能提升。典型的應用程式效能與 PHP 7.4 相當。

JIT 對 PHP 8 效能的相對貢獻

Just-In-Time compilation

類型系統和錯誤處理的改進

  • 更嚴格的算術/位元運算子類型檢查 RFC
  • 抽象 trait 方法驗證 RFC
  • 更正魔術方法的簽章 RFC
  • 重新分類引擎警告 RFC
  • 不相容方法簽章的致命錯誤 RFC
  • `@` 運算子不再抑制致命錯誤。
  • 使用私有方法繼承 RFC
  • 混合類型 RFC
  • 靜態返回類型 RFC
  • 內建函式的類型 電子郵件討論串
  • 針對 CurlGdSocketsOpenSSLXMLWriterXML 擴充套件,使用不透明物件取代資源

其他語法調整和改進

  • 允許在參數列表 RFC 和閉包使用列表 RFC 中使用尾隨逗號
  • 非擷取 catch RFC
  • 變數語法調整 RFC
  • 將命名空間名稱視為單個標記 RFC
  • Throw 現在是一個表達式 RFC
  • 允許在物件上使用 ::class RFC

新的類別、介面和函式

To Top