本站的主題是商業,創業,美食,葡萄酒,閱讀,網路科技。
這是我的 FB粉專 以及 IG,我比較常使用 Threads,歡迎大家追蹤互動~
PHP 8 正式版在去年 (2020年) 11月釋出,PHP 7 的最後一個版本就是 PHP 7.4 了。PHP 8 推出了一些新功能、新寫法,修正了 PHP 語言長期的字串 / 數字比較問題,推出了 Just-In-Time (JIT) compilation,加快執行效率。本篇文章就照著官方文件的順序,來走一遍 PHP 8.0 的新功能。
https://www.php.net/releases/8.0/en.php
Named Arguments 命名參數
舉例來講,function htmlspecialchars
的 prototype
function htmlspecialchars(
string $string,
int $flags = ENT_COMPAT,
string $encoding = null,
bool $double_encode = true
)
如果只是要指定其中一個參數 double_encode
,其他用預設值,PHP 8 可以這樣寫
htmlspecialchars($string, double_encode: false);
注意 flags
, encoding
都不用輸入。官方文件並提到,使用 Named Arguments 時參數不需要依照順序。
另外,如上方範例,Named Arguments 可以跟傳統輸入參數的方式混用。可以混用又沒有參數輸入的順序限制,會不會造成 ambiguous。如果用 coding convention 去限制,又會造成開發上的成本。larry 個人是對這個新功能持保留態度。
Constructor property promotion
在 PHP 8,constructor arguments 可以直接宣告成 class 的屬性。如下範例,注意 constructor arguments 前直接加了 public modifier。
class Point {
public function __construct(
public float $x = 0.0,
public float $y = 0.0,
public float $z = 0.0,
) {}
}
這樣 x, y, z 就直接宣告成 class 的屬性,不需要另外宣告
class Point {
// 不需要
public float $x;
public float $y;
public float $z;
...
}
這樣的確簡化了很多程式碼,但少了明文定義 class 的屬性。這樣真的不會造成混淆嗎?而且一樣,如果用 coding convention 去限制,又會造成開發上的成本。對這個新功能我還是持保留態度。
Match expression (match 表達式)
echo match (8.0) {
'8.0' => "Oh no!",
8.0 => "This is what I expected",
};
// print “This is what I expected”
match
表達式是 PHP 8 新出的。與 switch
判斷式比較,match
表達式會直接 return 數值,並用 strict comparison 做輸入/選項比較。相對的,switch
判斷式是 loose comparison。所以如果用 switch
,輸入 8.0,會先找到字串的 ‘8.0’。
寫法跟應用上 larry 還是不太習慣。match
大括號裡的東西比較像 array 的寫法,卻用大括號包住。應用上也有點 array 的味道,那直接使用 array 相關 function 反而還清楚一點。
Nullsafe operator
$country = $session?->user?->getAddress()?->country;
如果 $session
有值,return $session->user
。如果 $session->user
有值,return $session->user->getAddress()
,依此類推。從左到右,每一個問號會評估一次是否為 null,如果不為 null,繼續往右走。如果為 null,中斷在為 null 的部分,並 return null。
讀者可以評估一下上面 sample code,如果以 if else 來寫,或以三元運算子來寫,會有多少程式碼。用 nullsafe operator 除了簡潔以外,語意上也清楚。這個新功能 larry 會考慮使用。
Saner string to number comparisons 較健康的字串 / 數字比較
0 == 'foobar';
// PHP 7 和 PHP 7 以前會 return true
// PHP 8 會 return false
在 PHP 7 和 PHP 7 以前,上面 sample code 比較的方式是字串 “foobar” 先嘗試 cast 成數字,發現沒辦法 cast,所以 cast 成 0,所以上面比較式 return true。
這部分是 PHP 語言長期的一個缺陷,尤其當使用 in_array
, switch
等包含 implicit comparison 時,最好自己先判斷會不會有字串 / 數字比較的情況,不然 implicit comparison 判斷可能有誤。
PHP 8 修正了這個錯誤,除了將字串 cast 成數字外,也會將要比較的數字 cast 成字串,字串對字串比較。也就是比之前多了一個比較條件。
Just-In-Time (JIT) compilation
PHP 是直譯式語言 (interpreted language),要先裝好 PHP 套件,執行時 PHP code 會在 PHP 套件的環境裡,也可以說是透過 PHP 套件,不用編譯,直接執行。
PHP 8 推出的 Just-In-Time (JIT) compilation,會在執行期間,自動將某些 code 編譯,主要是 JIT 引擎分析會頻繁執行的 code,進行編譯,以達成效能的最大化。
原本 PHP 要透過一個 Zend virtual machine 與 CPU 溝通。有了 JIT compiler,部分程式碼會被編譯,快取在記憶體裡。當第二次執行該段 code,又編譯碼的快取還在的話,就會繞過 Zend virtual machine,直接執行編譯碼與 CPU 溝通。
PHP 8 的 JIT compiler 有兩種:Tracing JIT 與 Function JIT。
Function JIT 會編譯整個 PHP functions,但不會去分析程式碼結構。Tracing JIT 則會去找到這些重複又頻繁執行的 code,進行編譯。Tracing JIT 因為編譯的總量少,能加快編譯的速度 (節省主機資源),並在有限的記憶體 buffer,可以快取對整體效能最有幫助的編譯碼。
結論
PHP 8 大部份新寫法類型的功能,larry 是持保留態度,感覺對開發上沒有實質的幫助。PHP 8 修正了 PHP 語言長期的字串 / 數字比較問題,這件事需要知道一下。JIT 的部分也要知道,如果使用 PHP 8,JIT 的部分一定要正確 configure,開啟使用。
本站的主題是商業,創業,美食,葡萄酒,閱讀,網路科技。