如何為 PHP 8 準備 WordPress 網站

已發表: 2022-07-06

WordPress 網站需要 PHP,隨著 PHP 的發展,WordPress 也跟上了。 最近,PHP 7.4 已成為 WordPress VIP 平台上的默認 PHP 版本。 然而,隨著 PHP 7.4 於 2022 年 11 月結束其安全支持,WordPress 網站將需要升級以保持強大的安全性。 出於這個原因,WordPress VIP 平台將遷移我們所有的客戶應用程序以在 PHP 8.0 上運行。

以下是對更改的描述,以及我們的客戶和其他平台上使用 WordPress 的其他人可以做的準備步驟。

目錄

  • PHP 8.0 的故事
    • 新的功能
    • 在 PHP 和 WordPress 社區中增加支持
  • 如何查找 PHP 8.0 兼容性問題
    • 將 PHP_CodeSniffer 與 PHPCompatibility 標準一起使用
    • 解決 PHP 8.0 下已知的 PHP 致命錯誤的 PHP 警告
    • 創建自動化測試
    • 使用 PHPStan/Psalm 或其他靜態分析工具
  • 如何在 WordPress VIP 上開始使用 PHP 8.0
    • 在本地運行應用程序
    • 檢查拉取請求的 VIP 代碼分析機器人
    • 在您的 WordPress VIP 應用程序上啟用 PHP 8
    • 利用主動幫助
  • PHP 8.1 怎麼樣?

PHP 8.0 的故事

PHP 8.0 於 2020 年 11 月發布,提供了多項增強功能和功能,使新代碼(和更短的代碼)對錯誤更具彈性。

大多數開發人員會在 PHP 8.0 中發現很多好處。 但是,作為主要版本,它確實包含一些重大更改。 這使得從 PHP 7.4 到 PHP 8.0 的轉換比從 PHP 7.3 到 PHP 7.4 的轉換更加棘手。 具體來說,核心 PHP 有 49 處重大更改,整個 PHP 8 中有 169 處更改,包括您的代碼可能依賴的庫和擴展。

好消息是,一旦組織遷移到 PHP 8.0,他們將在 2023 年 11 月之前獲得核心 PHP 項目的安全支持。在那之後,組織將需要升級到 PHP 8.1,這是一個需要進行小得多的更改的次要版本。

新的功能

PHP 8.0 旨在 1) 修復邊緣情況和不一致性,使 PHP 成為一種更可靠和可預測的腳本語言,以及 2) 提供新功能來整體改進語言。 其中包括幾種新語法:

  • 更容易編寫嚴格類型的代碼,例如聯合類型、 staticmixed類型、 Stringable接口以及數字處理中的更改。
  • 減少您必須維護的代碼量,例如 nullsafe 運算符、構造函數屬性提升、 match運算符和非捕獲捕獲。
  • 簡化代碼,例如允許對像上的::class 、參數列表中的尾隨逗號、 str_contains()str_starts_with()str_ends_with()函數、拋出表達式、屬性。

它還包括命名參數。 但是,值得注意的是 WordPress 核心並未聲稱與此功能兼容。 因此,雖然您可以使用命名參數調用自己的自定義函數,但不應調用 WordPress 函數,因為參數名稱將來可能會更改而不會發出警告。

在 PHP 和 WordPress 社區中增加支持

每當發布包含新語法的新 PHP 版本時,整個 PHP 和 WordPress 社區都需要時間來支持新語法。

PHP 開發者工具

PHP 開發工具如 Composer、PHPUnit、PHP_CodeSniffer、PHPStan、Xdebug 和各種 IDE 都需要識別新版本 PHP 的新語法。 雖然 PHP 正在不斷開發中,但圍繞新版本的完整生態系統可用可能需要一段時間。 但是,通常,在最終版本準備就緒時,工具就可以準備就緒,因為開發工作是基於提前提供的alphabeta候選發布版本進行的。 所有這些工具以及更多工具現在都支持 PHP 8.0,這使其成為開發 PHP 代碼特別是開發 WordPress 的不錯選擇。

WordPress核心

接下來,WordPress 核心需要支持 PHP 8.0。 WordPress 項目在新版本 PHP 發佈時與它們的兼容性由來已久。 根據 Make WP 上這篇寫得很好的帖子,自 2020 年 12 月發布 WordPress 5.6 以來,WordPress 與 PHP 8.0 具有“測試版兼容性”。“測試版兼容性”是什麼意思? 這意味著 WordPress 可以在 PHP 8.0 上正常運行,但不支持在 WordPress 核心文件中聲明嚴格類型或在 WordPress 核心函數中使用命名參數等功能。

WordPress VIP平台

WordPress VIP 平台自 2022 年 5 月起支持 PHP 8.0(和 PHP 8.1),包括允許平台滿足企業需求的插件和功能套件。

第三方插件

WordPress 擁有數以萬計的插件,並且對 PHP 8.0 的支持程度差異很大。 例如,插件可能仍會使用新的保留字,或者傳遞給 PHP 原生函數的參數可能不是現在預期的類型。 因此,第三方插件可能是與 PHP 8.0 的不兼容性可能影響您的應用程序的一個領域。

您可以在下面了解如何檢查其中一些不兼容性。 選項包括要求上游個人/團隊進行修復並發布新版本,或者讓內部開發團隊或代理機構(如我們的特色合作夥伴之一)分叉插件並自行修復。

自定義插件

WordPress VIP 平台上的幾乎每個客戶都使用一個或多個自定義插件。 與第三方插件一樣,它們也需要進行兼容性檢查。 要求原始開發人員解決發現的問題通常是最好的做法。

第三方或自定義主題

雖然插件是兼容性問題的最可能來源,但不要忘記第三方和自定義主題也需要與 PHP 8.0 兼容。 檢查插件代碼兼容性的相同方法適用於主題代碼。

如何查找 PHP 8.0 兼容性問題

開發團隊可以使用四種主要方法來審查代碼以確定兼容性問題:

  1. 將 PHP_CodeSniffer 與 PHPCompatibility 標準一起使用。
  2. 解決 PHP 8.0 下的已知 PHP 警告,即 PHP 致命錯誤。
  3. 創建自動化測試。
  4. 使用 PHPStan/Psalm 或其他靜態分析工具。

將 PHP_CodeSniffer 與 PHPCompatibility 標準一起使用

PHP_CodeSniffer (PHPCS) 標記 PHP 文件並檢測是否違反了一組定義的編碼標準。 有 WordPress 編碼標準的軟件包,以及我們自己的 VIP 編碼標準(我們鼓勵客戶使用)。

還有稱為 PHPCompatibility 和 PHPCompatibilityWP 的包,這些標準分析了 PHP 跨版本兼容性的代碼庫。

因為結果取決於工具功能和準備情況,所以必須使用 PHPCompatibility 的develop分支,直到版本 10 發布。 版本 10 將包含與 PHP 8.0(和 PHP 8.1)兼容性相關的嗅探。 有關如何設置配置以使用develop分支的說明,請參閱我們的文檔。 版本 10 發布後,您可以改用該版本。

PHPCompatbilityWP 包構建在 PHPCompatibility 包之上,但對 WordPress 核心自身包含的向後兼容性項目進行了一些檢查。

設置好 PHPCS 和 PHPCompatibility/PHPCompatibilityWP 後,您可以運行檢查:

 phpcs --standard=PHPCompatibilityWP --severity=1 --runtime-set testVersion 8.0- --extensions=php <path-to-code>

如果您想從小處著手, <path-to-code>可以是單個自定義或第三方插件或主題,如果您想查看所有需要調查和解決的違規行為,則可以是整個存儲庫。

掃描步驟不會檢測到所有可能的 PHP 版本兼容性問題(例如不正確的運行時值類型),但它們將有助於識別與語法相關的最常見問題。

解決 PHP 8.0 下已知的 PHP 致命錯誤的 PHP 警告

PHP 8.0 看到了一些重新分類的引擎警告,其中警告變成了致命錯誤和 TypeError 異常(並且一些通知變成了警告)。 在 PHP 7.4 下要查找的 PHP 警告文本是:

  • Attempt to assign property '*' of non-object
  • Attempt to modify property '*' of non-object
  • Attempt to increment/decrement property '*' of non-object
  • Creating default object from empty value
  • Cannot use a scalar value as an array
  • Cannot add element to the array as the next element is already occupied
  • Cannot unset offset in a non-array variable
  • Only arrays and Traversables can be unpacked
  • Invalid argument supplied for foreach()
  • Illegal offset type
  • Illegal offset type in isset or empty
  • Illegal offset type in unset
  • Cannot assign an empty string to a string offset
  • Division by zero
  • Use of undefined constant *

修復這些警告對於應用程序與 PHP 8.0 兼容至關重要。

注意:在 PHP 8.0 下還有其他致命錯誤,在 PHP 7.4 下甚至不是警告。 示例包括:

  • 除構造函數外,私有方法不得聲明為 final。
  • 魔術方法的簽名無效。
  • 抽象特徵方法簽名驗證
  • parent::與父類一起使用。
  • 不兼容的重載方法簽名(Liskov 替換原則)

解決這些已知的變化是一個很好的起點。 所有內部 PHP 函數都會持續拋出 TypeError,例如當傳遞了無效的參數類型時,即使沒有聲明嚴格的類型檢查也是如此。

另外,請注意@運算符將不再消除 PHP 8.0 下的致命錯誤。

自然,您的應用程序理想情況下應該不產生錯誤、警告和通知。 我們鼓勵您解決您發現的任何問題。 8.x 下的一些 PHP 警告將是 PHP 9.0 下的致命錯誤,例如,可能導致 PHP 8.x 下的邏輯不正確。 在發布前和發布後構建開發時間以解決此類問題以及在開發過程中“逃避發現”的問題是最佳實踐。 這也是對網站穩定性的投資,以及準確滿足相關功能的驗收標準的能力。

創建自動化測試

有許多不同類型的自動化測試,但這裡我們的意思是:

  • 單元測試——模擬任何 WordPress 定義的函數或類,並且不需要數據庫實例即可運行測試。
  • 集成測試——加載 WordPress 並使用實際的測試數據庫

這個話題太大了,無法在這裡很好地涵蓋,但有幾點需要考慮:

  • 結果取決於測試套件的完整性。 如果您沒有很多測試,那麼您將缺乏必要的覆蓋範圍來確保兼容性。
  • 使用嚴格的斷言。 例如,使用assertEquals()進行鬆散比較,而assertSame()也檢查類型。
  • 使用嚴格的代碼覆蓋率。 將beStrictAboutCoversAnnotations=”true”forceCoversAnnotations=”true”添加到 PHPUnit 配置文件中,然後使用@covers註釋查找跨測試的國際代碼覆蓋率的準確級別。
  • 測試快樂(基於預期輸入的行為)和不快樂(基於意外輸入的行為)路徑,以確保函數以預期的方式失敗,因為這是最嚴格相關問題發生的地方。
  • 在 PHP 8.0 上運行測試。 對於集成 (WordPress) 測試,2021 年對使用更高版本的 PHPUnit 解鎖的 WordPress 核心測試套件進行了更改,後者又支持 PHP 8.0。 WP Test Utils 包支持這一點,其中包括 PHPUnit Polyfills、Brain Monkey 和 Mockery 支持、WordPress 函數的附加函數存根,以及對所有 WP 原生測試實用程序(如用於內容創建的工廠方法)的訪問。
  • 考慮在嘗試修復之前編寫測試,以更加確信兼容性更改已成功。

使用 PHPStan/Psalm 或其他靜態分析工具

雖然 PHPCS 會捕獲一些不兼容性,但 PHPCS 並非旨在捕獲一些運行時更改。 一個可能會被忽略的例子是原生 PHP 函數對可以作為參數傳遞的類型更加嚴格。

PHPStan、Psalm 等工具或其他靜態分析工具可以提供幫助。 但是,為了最有效,它們要求您的代碼庫要么使用嚴格類型(代碼中的參數和返回類型),要么正確記錄(DocBlocks 中的@param@return行)。

這些工具通常具有允許首先修復最低級別問題的規則級別,然後逐漸進一步集成該工具以提高代碼庫的質量。

您可以通過 phpstan-wordpress 和 psalm-plugin-wordpress 等擴展為 WordPress 核心代碼添加類型知識。

配置後,每次運行都會突出顯示您將意外類型傳遞給函數的位置,這可能會導致拋出致命的 TypeError 異常。 這些中的每一個都需要修復。

在許多情況下,您可以通過使用 try-catch 塊或類型轉換來抑制 TypeError 異常。 但是,我們強烈建議您不要這樣做。 解決根本原因將導致代碼更強大、更不脆弱和更容易出錯,並且從長遠來看幾乎總能得到回報。

如何在 WordPress VIP 上開始使用 PHP 8.0

在本地運行應用程序

在本地運行應用程序實例是能夠檢測和修復任何兼容性問題的明智的第一步。 雖然您可以使用任何本地開發環境,但為了確保與 WordPress VIP 平台的最佳對等性,我們推薦 VIP 本地開發環境。 通過運行命令vip dev-env create --php=8.0 (使用 VIP-CLI 2.9.5 或更高版本)然後完成設置嚮導的其餘部分,您的應用程序將使用 PHP 8.0 在本地運行。

檢查拉取請求的 VIP 代碼分析機器人

如果您查看在 wpcomvip 組織下對您的存儲庫發出的任何拉取請求,您將看到 VIP 代碼分析機器人為您提供有關 PHPCS、PHP linting 和 SVG linting 的反饋。

對於 PHP Linting 步驟,機器人將使用用於部署存儲庫的應用程序的任何 PHP 版本對 PHP 代碼進行 lint。 如果該版本是 PHP 7.4,它現在也將自動使用 PHP 8.0 進行 lint,為即將到來的切換做準備。

在您的 WordPress VIP 應用程序上啟用 PHP 8

一旦您在本地完成了盡可能多的檢查和修復,就可以在您的 WordPress VIP 應用程序上啟用 PHP 8.0。 從您的最低環境開始,並在升級到生產環境之前檢查一切是否正常(包括通過 vip-cli 的 PHP 日誌或 VIP 儀表板中的健康日誌)。

要在環境中啟用 PHP 8.0,請打開 Zendesk 票證,讓我們知道您希望在哪個應用程序和環境上啟用它。

我們很快將在 VIP 儀表板上發布一項新功能,以允許更改 PHP 版本而無需打開工單。 隨時查看大廳以獲取最新信息。

利用主動幫助

Premier 客戶的客戶團隊已經與客戶聯繫,討論我們如何為他們提供支持。 他們將從 PHPCS 收到結果,並提供有關如何自行運行這些檢查的指導。 將成為致命錯誤的 PHP 警告也將被突出顯示,讓它們在解決不兼容性方面領先一步。

PHP 8.1 怎麼樣?

WordPress VIP 平台也支持 PHP 8.1。 PHP 8.0 和 PHP 8.1 之間的更改比 PHP 7.4 和 8.0 之間的更改要少,這意味著要解決的不兼容性應該更少。

PHP 8.1:

  • 在 2023 年 11 月之前獲得 PHP 核心開發人員的積極支持,在 2024 年 11 月之前獲得安全支持。
  • 每秒可以處理比 PHP 8.0 更多的請求。
  • 在 WordPress 5.9 及更高版本上具有“beta 兼容性”支持——這意味著在準備 PHP 9 時有一些棄用通知,但不會影響 WordPress 核心的行為。

PHP 8.0 所需的有用更改(例如使用嚴格類型化的代碼和添加自動化測試)將有助於 PHP 8.1 的推出,以及 WordPress 6.1、6.2、6.3 及更高版本的升級,以及您所做的任何功能發布。 QA 流程通常是瓶頸,因此使用我們概述的一些工具和方法可以減少手工勞動並讓您在部署這些更改時更有信心。

如果客戶對 PHP 8.0 有任何疑問,請向我們開票。