7 個 PHP 8 新特性,效能優化與更簡潔的程式語法

woman in black shirt using laptop computer

PHP 是一種最受歡迎的伺服器端指令碼語言,最初是在 1994 年由 Rasmus Lerdorf 創建的。多年來,它經歷了無數的變革,從一個用於創建動態網頁的簡單工具演變為一種用於網頁開發、電子商務,社群網站、討論區等等等全面語言。****

PHP 8 的推出標誌著其發展歷程中的一個重要里程碑。這一版本帶來了幾個主要的特性、性能改進,以及更加適合開發者的語法,不論你是一名經驗豐富的 PHP 開發者,還是一名希望深入了解伺服器端指令碼世界的初學者,理解 PHP 8 的新功能,對開發品質和效率都有明顯的加強。

PHP 8 新特性不僅僅是一次更新;它是一場即將重新定義開發者如何看待 PHP 編碼的革命。所以,不用再猶豫了,直接升級 PHP 8。

#1 Just-In-Time Compilation (JIT)

在 PHP 8 中引入的一個引人注目的特性就是即時編譯,通常簡稱為 JIT。雖然 PHP 歷來是一種解釋型語言,但 JIT 通過將 PHP 的部分位元組碼編譯成原生機器碼,將其提升到了一個全新的層次,讓代碼執行速度更快,從而提高了您的 PHP 應用程式的性能。

JIT 編譯器的工作原理是識別代碼中的「熱點」區段,也就是您的應用程序中經常運行的部分。它隨後將這些「熱點」位元組碼翻譯成原生機器指令,這些指令可以直接由計算機的 CPU 執行。因此,這些代碼段的後續運行速度顯著提高。

如果您正在進行計算密集型的任務,例如機器學習算法、實時數據分析,甚至是高性能遊戲後端,JIT 編譯器可以使您的 PHP 代碼運行速度,達到先前被認為是 PHP 無法達到的速度。

#2 Named Arguments

另一個 PHP 8 帶來的突破性特性是具名參數。在早期的 PHP 版本中,傳遞給函數的參數順序至關重要,您需要記住參數的序列,這對於參數清單很長的函數來說可能是一個挑戰。

具名參數完全改變了這一點,有了這個特性,您可以通過名稱來指定參數,使代碼更易讀和更不容易出錯。例如,不再需要寫 array_slice($array, 2, 4, true),您現在可以寫 array_slice(array: $array, offset: 2, length: 4, preserve_keys: true)。這使函數擁用自我解釋意涵,減少了開發者的認知負擔。

//原本是
array_slice($array, 2, 4, true);

//改成
array_slice(array: $array, offset: 2, length: 4, preserve_keys: true);

假設有個畫矩形的 function

function drawRectangle($width, $height, $color = 'black') {   
    // Drawing logic here 
}

以前,你會這樣呼叫。

drawRectangle(200, 100, 'red');

現在可以使用具名參數呼叫

drawRectangle(width: 200, height: 100, color: 'red');

再來個範例

<?php

function greet(string $name, int $age, string $city) {
    return "Hello, my name is $name. I am $age years old and I live in $city.";
}

// 傳統呼叫方式
echo greet("Alice", 30, "New York");

// 使用具名參數
echo greet(age: 30, city: "New York", name: "Alice");

// 使用具名參數不用在意參數順序
echo greet("Alice", age: 30, city: "New York");

?>

#3 Constructor Property Promotion

建構子屬性提升(Constructor Property Promotion)是 PHP 8 帶來的另一個令人興奮的特性。在先前的 PHP 版本中,您需要手動聲明類別的屬性,然後在建構子中進行初始化,這經常導致冗長和重複的代碼。

現在,您可以直接在建構子參數中聲明屬性,有效地將屬性聲明和初始化,合併為一個單一步驟。例如,不再需要寫:

class Person {
    public string $name;
    public int $age;

    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

在 PHP 8 中,您可以如下簡化上述代碼:

class Person {
    public function __construct(
        public string $name,
        public int $age,
    ) {}
}

如您所見,我們不再需要單獨宣告屬性($name$age)或在建構子中初始化它們。相反,我們直接在建構子簽名中宣告並初始化它們。

使用該類別的方式仍然相同:

$person = new Person("John", 30);
echo $person->name; // 輸出:John
echo $person->age;  // 輸出:30

這個功能使得代碼更乾淨、更易讀,並且減少錯誤。通過移除在宣告和初始化屬性時涉及的重複步驟,它提高了生產力和代碼的可維護性。

#4 The Nullsafe Operator

PHP 8 中引入的空值安全運算符(Nullsafe Operator)是一個受歡迎的新增功能,它有助於減少圍繞空值檢查的重複代碼。

在早期的 PHP 版本中,開發人員必須在使用訪問對象上的屬性或方法之前,繁瑣地檢查空值,這導致代碼較不整潔和更難維護。

有了空值安全運算符(用 ?-> 表示),您現在可以在可能為空的變數上訪問方法和屬性,而不會導致嚴重錯誤。

例如,考慮以下代碼片段:

// 傳統方式 
if ($user !== null) {   
    $country = $user->getAddress()->getCountry(); 
}

// 使用空值安全運算符 
$country = $user?->getAddress()?->getCountry();

在這個例子中,如果鏈中的任何部分返回 null,整個表達式會短路並評估為 null。這消除了對多個空值檢查的需要,從而使代碼更簡潔和更容易閱讀。

值得注意的是,應謹慎使用空值安全運算符。過度使用可能會掩蓋實際需要處理的問題。然而,當適當使用時,它可以顯著提高代碼的可讀性和可維護性。

#5 Union Types

聯合類型是 PHP 8 中一個重要的增強功能,為類型聲明提供了更多的表達能力。在 PHP 8 之前,開發者必須選擇單一類型聲明或者完全不用,這使得代碼較不穩健,更容易出錯。

聯合類型允許開發者為函數參數、返回類型和類屬性指定多個類型。這使代碼更易讀、自我文檔化,以及減少註釋非常有用。

從語法上來看,這些類型是由一個豎線 | 分隔的:

public function setNumber(int|float $number): void {   
// 函數邏輯在這裡 
}

在這個例子中,函數 setNumber 可以接受整數和浮點數,為代碼設計提供更大的靈活性。

自我文檔化

程式碼本身就很有說明意圖,不需太多註解就有文件說明的功能,就是自我文檔化。
如果一段程式需要很多註解說明,可能需要的是改寫,而不是更多註解。

#6 Match expression

在 PHP 8 中,match 表達式為一種更強大,更簡潔的 switch 語句替代方案,這個新特性改善了代碼的可讀性和維護性,同時減少了錯誤的可能性。

優勢

  1. 簡潔性:您不再需要寫多個 casebreak 關鍵字。
  2. 類型安全match 表達式是嚴格類型匹配的,這減少了不期望的行為。
  3. 返回值match 直接返回匹配分支的值,讓您能更簡單地將其賦值給變數。

Ex 1:

$number = 5; 
$result = match ($number) {     
  1, 2, 3 => 'Small number',     
  4, 5, 6 => 'Medium number',     
  default => 'Unknown number', 
}; 
echo $result;  // 輸出:Medium number

Ex 2:


$day = 'Monday';

$result = match ($day) {
    'Monday' => 'Start of the workweek'
    'Tuesday', 'Wednesday', 'Thursday' => 'Working days',
    'Friday' => 'Last working day',
    'Saturday', 'Sunday' => 'Weekend!',
    default => 'Invalid day',
};

echo $result;  // 輸出 "Start of the workweek"

#7 New String Helpers

PHP 8 引進了各種新功能,其中包括一組實用的字串(string)助手函數,以簡化字串操作任務。以下是一些新的字串助手以及它們的使用示例:

1. str_contains()

此函數檢查一個給定的子字串是否存在於一個字串中。

範例:

if (str_contains('你好 世界', '世界')) {     
  echo '字串包含 "世界"。'; 
} else {     
  echo '字串不包含 "世界"。'; 
}

2. str_starts_with()

此函數檢查一個字串是否以一個給定的子字串開頭。

範例:

if (str_starts_with('你好 世界', '你好')) {     
    echo '字串以 "你好" 開頭。'; 
} else {     
    echo '字串不以 "你好" 開頭。'; 
}

3. str_ends_with()

此函數檢查一個字串是否以一個給定的子字串結尾。

範例:

if (str_ends_with('你好 世界', '世界')) {     
    echo '字串以 "世界" 結尾。'; 
} else {     
    echo '字串不以 "世界" 結尾。'; 
}

這些 PHP 8 中的新字串助手使字串操作任務更容易和更可讀,從而提高了代碼質量並減少了出錯的機會。

這些優化和增強不僅僅是語法糖,而且具有實質性的性能好處。例如,JIT 編譯顯著提高了代碼的執行速度,使 PHP 在特定用例下與 Python 和 JavaScript 等語言更具競爭力。

PHP 8 的變革力量不容低估,它可以是更現代、可維護和可擴展的網頁應用程式的催化劑。隨著新功能不斷前進,和持續演進的最佳實踐,PHP 將會繼續證明是不可忽視的程式語言。


更多參考內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *