跳至主要內容
問題與解答
PHP 8 常見的相容性問題與棄用警告

PHP 8 常見的相容性問題與棄用警告

問:
升級 PHP 8 後出現大量警告 動態屬性的棄用通知怎麼處理? 傳 null 給函式會有問題嗎? 舊系統要修還是重做?
答:

PHP 8 對舊程式碼的影響

PHP 8 系列在錯誤處理與型別檢查上比 PHP 7 嚴格得多。過去只是警告的情況,很多在 PHP 8 變成致命錯誤。

這對維護多年的舊系統影響最大——程式一直正常運作,升級後卻出現大量錯誤。

以下整理最常遇到的幾類。

一、警告升級為錯誤

PHP 8.0 把許多原本的警告改為拋出錯誤。最常見的幾種:

  • 存取不存在的陣列鍵——過去是通知,現在仍是警告但更明顯
  • 對非陣列使用陣列語法——現在會拋出錯誤
  • 除以零——現在拋出 DivisionByZeroError
  • 參數數量或型別不符——內建函式現在會拋出 TypeError

典型的修法

// 舊寫法
$name = $data['name'];

// 建議
$name = $data['name'] ?? '';

二、傳入 null 的棄用警告

PHP 8.1 起,對內建函式的非可為空參數傳入 null 會產生棄用通知。

這是舊系統升級後最常見的大量警告來源,因為過去這樣寫完全正常。

// 會產生棄用通知
$len = strlen($maybeNull);
$trimmed = trim($maybeNull);
$upper = strtoupper($maybeNull);

// 建議
$len = strlen($maybeNull ?? '');
$trimmed = trim((string)($maybeNull ?? ''));

這類通知現在不會中斷程式,但在未來的版本可能變成錯誤。 建議逐步修正而不是忽略。

三、動態屬性的棄用

PHP 8.2 起,在未宣告的類別屬性上直接賦值會產生棄用通知。

class User {
    public $name;
}

$u = new User();
$u->email = 'a@example.com';   // 未宣告,產生棄用通知

三種處理方式

// 方式一:明確宣告(建議)
class User {
    public $name;
    public $email;
}

// 方式二:加上屬性標註(過渡用)
#[\AllowDynamicProperties]
class User { }

// 方式三:實作魔術方法自行管理

舊框架與 CMS 大量使用動態屬性,升級到 8.2 時會產生非常多通知。若無法立即重構,可先用方式二過渡,但應排入改善計畫。

四、字串與數字的比較行為改變

PHP 8.0 調整了非嚴格比較的規則。字串與數字比較時,改為以字串方式比較(除非字串是數值形式)。

// PHP 7:true('foo' 被轉為 0)
// PHP 8:false
var_dump(0 == 'foo');

// 兩者皆為 true
var_dump('1' == '01');

這個變更通常讓行為更符合直覺,但依賴舊行為的程式可能出現邏輯錯誤——而且不會有錯誤訊息,只是結果不同。

建議在比較時使用嚴格比較

if ($value === 'expected') { }

五、已移除的函式與擴充

各版本陸續移除了一些舊有的功能。常見的包含:

  • 舊的 MySQL 擴充——早已移除,應改用 mysqli 或 PDO
  • 魔術引號相關函式
  • 部分字串與陣列函式的舊別名
  • each()——已移除,改用 foreach

檢查方式

用靜態分析工具掃描,可以在不執行的情況下找出使用了已移除功能的位置。

六、建構子與方法簽章的檢查更嚴格

子類別覆寫父類別方法時,參數與回傳型別的相容性檢查變嚴格。不相容時會直接拋出致命錯誤。

這在繼承層級較深的舊框架中特別容易遇到。

七、字串內插與大括號語法

部分舊的字串內插寫法已被標記為棄用:

// 已棄用的寫法
echo "值是 ${var}";

// 建議
echo "值是 {$var}";
echo "值是 $var";

怎麼有系統地處理

一、先讓所有問題可見

在測試環境設定:

error_reporting = E_ALL
display_errors = Off
log_errors = On

然後完整走過所有功能,收集日誌。

二、分類處理

類型優先度處理
Fatal error最高必須修,否則功能壞掉
Warning可能造成邏輯錯誤
Deprecated下一版的致命錯誤,應排入計畫
Notice逐步改善

三、從共用的程式碼開始改

同樣的問題可能散布在數十個檔案中。先找出共用的函式庫或基底類別,改一處可能解決很多地方。

四、不要在正式環境隱藏棄用通知了事

error_reporting 調低確實能讓日誌乾淨,但問題仍然存在,只是被藏起來了。

正式環境可以不記錄棄用通知以免日誌爆量,但測試環境必須看得到,並排入改善計畫。

老系統的現實建議

如果系統很舊、原始碼被大幅改過又沒有文件,升級的工時可能超過重建。

判斷的參考:

  • 錯誤數量龐大且散布廣泛
  • 使用了已無維護的框架或套件
  • 沒有測試可以驗證修改是否正確
  • 原始碼與官方版本差異太大,無法直接套用官方更新

這種情況下,在乾淨的環境重建,往往比持續修補更划算——見網站改版的流程

本文的設定與語法以 PHP 8.x 為例,實際的參數、預設值與支援狀態可能因版本與發行版而異。各版本的支援時程請以 PHP 官方公告為準。套用前請先在測試環境驗證,並確實備份原設定檔。

發表於2026-08-05   更新於2026-08-20
免費諮詢 · 1 個工作天內回覆

準備好讓網站 開始幫你帶生意了嗎?

不論是要做新網站、救舊網站,還是只想先聊聊方向——先諮詢,不用先付錢,我們照實給你建議。

1 個工作天回覆免費諮詢與報價費用白紙黑字26 年找得到人
免費諮詢
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢 LINE諮詢 03-4020420 臉書傳訊