WordPress 官方建議的 PHP 版本是 8.3 以上,新站直接開在 8.3 以上,既有的站則先升到還有安全性更新的版本,再往上試。官方的環境需求同時列出 MariaDB 10.11 以上或 MySQL 8.0 以上,並且註明 PHP 7.4 雖然還能跑,但已經結束官方支援、不再收到安全性更新。這裡要先講清楚一件事:決定你能升到哪一版的,從來不是 WordPress 核心,而是佈景與外掛裡最舊的那一支程式碼。
所以這篇不談「哪一版效能比較好」——那個問題我們在WordPress 網站很慢怎麼辦裡用同一台主機的實測回答過了。這篇只回答會讓人卡住的那一半:舊外掛到底會在哪一版壞掉、壞的時候長什麼樣子、切換前怎麼先驗、切壞了怎麼回去。下面的數字全部來自我們自己這台主機,上面並存 15 個 PHP 版本(ea-php53 到 ea-php85),可以直接把同一段程式碼丟給不同版本跑。
先分清楚兩件事:Deprecated 不會讓網站壞掉,Fatal error 才會
升級 PHP 版本之後最常見的情境,是網站打開一看滿滿的黃色警告,於是當場退回舊版本,從此再也不敢碰。這是誤判。PHP 的訊息分成幾個等級,跟「網站有沒有壞」直接相關的只有三種:
| 訊息類型 | 網站會怎樣 | 該怎麼處理 |
|---|---|---|
| Deprecated(已淘汰) | 程式照常執行、頁面照常輸出,只是多印一行警告 | 排進修正清單,不必退版本。正式站本來就該關閉畫面上的錯誤顯示 |
| Fatal error(致命錯誤) | 執行到那一行就中斷,通常就是白畫面或半截頁面 | 立刻退回上一個版本,先讓網站活著,再處理那支外掛 |
| Parse error(語法解析錯誤) | 整個檔案連執行都不會開始,比 Fatal error 更早失敗 | 同上,而且代表那段程式碼的寫法在新版已經不合語法,一定要改 |
差別很重要:看到 Deprecated 就退版本,等於因為預告片而取消整部電影。真正要退回去的訊號只有兩個——頁面中斷,或是後台進不去。
同一段程式碼丟給七個 PHP 版本:舊寫法到底在哪一版壞掉
我們在同一台主機上,把九段常見於舊佈景與舊外掛的寫法,分別丟給 PHP 5.6.40、7.0.33、7.2.34、7.4.33、8.0.30、8.1.34、8.5.10 執行,記錄每一版實際吐出來的訊息。結果整理如下(「正常」代表沒有任何警告):
| 舊寫法 | 5.6 / 7.0 | 7.2 / 7.4 | 8.0 | 8.1 以後 |
|---|---|---|---|---|
each() 走訪陣列 |
正常 | Deprecated | Fatal error:Call to undefined function | Fatal error |
create_function() 動態建函式 |
正常 | Deprecated | Fatal error:Call to undefined function | Fatal error |
mysql_connect() 舊資料庫函式 |
5.6 有、7.0 起已移除 | 已移除 | 已移除 | 已移除 |
$s{0} 大括號取字元 |
正常 | 7.2 正常、7.4 Deprecated | Fatal error:no longer supported | 8.5 實測為 Parse error |
| 必填參數寫在選填參數後面 | 正常 | 正常 | Deprecated | Deprecated(訊息更明確) |
把 null 傳給字串參數,例如 strlen(null) |
正常 | 正常 | 正常 | 8.1 起 Deprecated |
FILTER_SANITIZE_STRING 過濾常數 |
正常 | 正常 | 正常 | 8.1 起 Deprecated |
utf8_encode() 編碼轉換 |
正常 | 正常 | 正常 | 8.1 仍正常;8.5 實測 Deprecated(訊息標明自 8.2 起) |
| 物件上直接新增未宣告的屬性 | 正常 | 正常 | 正常 | 8.1 仍正常;8.5 實測 Deprecated(自 8.2 起) |
這張表真正的用途,是把「不敢升級」變成「知道會撞到什麼」。可以看出一個很明確的分界:7.x 之內大多只是警告,跨到 8.0 才會出現第一批真正的中斷。換句話說,如果你的網站現在停在 7.4,升到 8.0 是要認真測的那一步;而如果你停在 5.6 或 7.0,那一步更早就已經在 7.0 移除 mysql_connect() 時發生過了。
停在舊版本的真正代價
「反正網站還會動」是停在舊版最常見的理由,但會動跟有沒有人維護是兩件事。已經結束支援的 PHP 版本不再收到安全性更新,之後被公開的漏洞就一直留在那裡。我們把「可切換的 PHP 版本」列為主機端防線之一,原因也在這裡——它讓「先升到還有更新的版本、再慢慢處理不相容的外掛」變成可行的選項,而不是二選一。這一段的完整脈絡寫在WordPress 被駭怎麼救。
切之前先確認三件事,順序不要顛倒
一、目標版本上有沒有你用得到的擴充套件
這是最容易被跳過、卻最常出事的一項。很多人以為 PHP 版本越新、東西越齊,實際上擴充套件是主機端逐版本各自安裝的,不是跟著版本號自動長出來。同一台機器上實際用 php -m 數出來的數量就不一樣:PHP 5.6.40 有 53 個、7.4.33 有 55 個、8.1.34 有 50 個、8.5.10 有 59 個。
逐項比對之後,差異更具體:
- 7.4 有、8.5 沒有的:
enchant、memcache、tidy、xmlrpc。舊程式如果直接呼叫這幾個擴充套件提供的函式,切上去就會是 Fatal error,而且錯誤訊息只會說「找不到這個函式」,不會告訴你是擴充套件沒裝。 - 8.5 有、7.4 沒有的:
calendar、igbinary、lexbor、mcrypt、msgpack、random、shmop、uri。 - 同一台機器上,8.1 沒有
imagick,而 7.4 與 8.5 都有。這是最好的反例:版本號比較新,模組反而缺。偏好用 Imagick 處理縮圖或 PDF 的外掛,切到 8.1 會退回 GD 或直接失效,切到 8.5 又恢復正常。
所以正確的動作不是憑印象,是切換之前先看一眼目標版本的擴充套件清單。cPanel 裡看得到,SSH 進去下 php -m 也看得到,WordPress 後台的「網站健康」頁面同樣會列出目前的 PHP 版本與已載入的模組。
二、佈景與外掛各自標示的相容範圍
把佈景、外掛列成一張清單,逐一去看它標示支援到哪一版、最後更新是什麼時候。這一步不是為了找出「能不能升」,而是為了找出那一兩支拖住整個網站的外掛——通常是客製的、或是多年沒更新的。找到它之後才有得談:換掉、改掉,或是把它所在的那個網站先留在舊版本。
三、先有一份還原得回來的備份,並且先在測試網址上試
切版本本身是可逆的,但切上去之後被觸發的資料寫入不一定可逆。順序是:先確認備份能還原(不是「主機商有備份」,是你自己驗過能還原的那一份),再切。備份要怎麼驗收才算數,寫在WordPress 被駭怎麼救那篇的第三節。
如果手上有測試網域或子網域,把網站複製一份先切,是成本最低的做法;順帶一提,複製一份到別的網址時最容易踩到的是資料庫裡寫死的舊網址,那個坑整理在WordPress 搬家怎麼搬不掉排名。
cPanel 怎麼切、切壞了怎麼回去
在 cPanel 主機上,切換 PHP 版本不需要開工單、不需要等主機商排程:
- 進 cPanel 找 MultiPHP Manager。它會列出這個帳號底下所有網域,以及每個網域目前使用的 PHP 版本。
- 勾選要改的網域,在右上角選擇目標版本,按套用。以網域為單位,同一個帳號底下的不同網域可以各自使用不同版本。
- 立刻開網站首頁與後台各看一眼。不是看「有沒有錯誤訊息」,是看頁面有沒有完整輸出、後台能不能登入、文章能不能存檔。
- 要細到目錄層級,則是在該目錄的
.htaccess放一行對應的處理常式設定,讓那個子目錄維持舊版本,其他地方照新版本跑。 - 切壞了就切回去——回到同一個畫面選回原本的版本、套用,網站會立刻回到切換前的行為。這也是為什麼前面說「Fatal error 才退版本」是安全的建議:退回去的成本只有幾秒鐘。
我們這台主機上的實際環境
並存 15 個 PHP 版本(ea-php53 到 ea-php85),切換即時生效、隨時可以切回來,也不會因為切版本另外收費;每個網域、每個子目錄可以各自使用不同版本。目前官網本身跑在 PHP 8.5.10、MySQL 8.4.9、網頁伺服器 LiteSpeed。關於虛擬主機上到底能自己控制到什麼程度,逐項寫在虛擬主機能做到什麼;挑主機時該看哪幾項規格,寫在WordPress 主機怎麼選。
升上去之後,把 Deprecated 清掉的順序
網站活著之後才輪到整理。建議的順序是:先關掉正式站畫面上的錯誤顯示、改成寫進錯誤紀錄檔(不然警告會直接印給訪客看),再從紀錄檔裡挑出現次數最多的那一支處理。多數情況下,一支外掛就佔掉整份紀錄的大半,換掉它,畫面就乾淨了。
如果公司裡沒有人固定做這件事,它實際上就是沒人做——這也是我們把 PHP 版本檢查、核心與外掛更新放進網站代管範圍的原因。委外範圍到底該包到哪裡,可以參考我們的一條龍服務說明。
常見問題
Q:WordPress 該用哪個 PHP 版本?直接給一個答案的話是哪一版?
WordPress 官方標示的建議環境是 PHP 8.3 以上,搭配 MariaDB 10.11 以上或 MySQL 8.0 以上;官方同時註明 PHP 7.4 仍可運作,但那些版本已經結束官方支援,不再收到安全性更新。實務上的答案分兩種情況:新站直接開在 8.3 以上,沒有任何理由從舊版開始;既有的站則不要一次跳到最新,先升到還有安全性更新的版本、把網站跑起來,再往上試。真正決定你能升到哪一版的不是 WordPress 核心,而是佈景與外掛裡最舊的那一支程式碼。
Q:升上 PHP 8 之後看到一堆 Deprecated 訊息,網站是不是壞了?
不是。Deprecated 是「這個寫法之後會被拿掉」的預告,程式照常執行,頁面照常輸出;真正會讓網站當掉的是 Fatal error 與 Parse error 這兩種。我們在同一台主機上實測:each() 與 create_function() 在 PHP 7.2 只是 Deprecated、網站還會動,到 8.0 就變成 Fatal error 直接中斷;$s{0} 這種大括號取字元的寫法在 7.4 是 Deprecated、8.0 變成 Fatal error、8.5 連解析都過不了,回的是 Parse error。所以看到 Deprecated 的正確反應是排進修正清單,不是退回舊版;看到 Fatal error 或 Parse error 才是立刻退回去。
Q:可以只讓某一個網站或某個目錄用不同的 PHP 版本嗎?
可以。cPanel 的 MultiPHP Manager 是以網域為單位指定版本,同一個主機帳號底下的不同網域可以各自不同;要再細到目錄層級,則是在該目錄的 .htaccess 放一行對應的處理常式設定。這在升級期間很有用:主站先升上去,只把還沒改完的舊系統留在舊版本,不必為了一支外掛把整個帳號卡在沒有安全性更新的版本上。我們這台主機上並存 15 個 PHP 版本(ea-php53 到 ea-php85),切換即時生效、隨時可以切回來,也不會因為切版本而另外收費。