Notice: Undefined variable 是 PHP 開發最常見的提示,雖不中斷執行,但暴露程式碼潛在邏輯缺陷。本文系統整理 php.ini 設定、執行期控制、程式碼防禦寫法 三層面解決方案,並說明為何不建議直接關閉提示。
<?php
echo $username; // 直接使用未賦值變數 → Notice
// 正確寫法
$username = $_GET['username'] ?? '訪客';
echo $username;
PHP 允許未宣告變數直接使用(視為 null),但最佳實踐要求先定義、後使用。
; 顯示除 E_NOTICE 外所有錯誤(生產環境建議)
error_reporting = E_ALL & ~E_NOTICE
; 或僅顯示嚴重錯誤
error_reporting = E_ERROR | E_WARNING | E_PARSE
; 完全關閉錯誤顯示(生產環境必須)
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
注意:register_globals = On是極度危險的舊設定(PHP 5.4 已移除),絕對不可開啟,否則 `?var=value` 會自動建立全域變數,導致嚴重安全漏洞。
<?php
// 檔案最頂端(輸出前)設定
error_reporting(E_ALL & ~E_NOTICE); // 忽略 Notice
// error_reporting(0); // 完全關閉(不建議,除錯極難)
// 或使用 ini_set
ini_set('error_reporting', E_ALL & ~E_NOTICE);
ini_set('display_errors', '0'); // 不顯示於頁面
ini_set('log_errors', '1'); // 寫入錯誤日誌
?? (PHP 7+)$name = $_POST['name'] ?? '匿名'; // 若不存在或 null,用預設值
$page = $_GET['page'] ?? 1;
isset() / empty() 判斷// isset:變數存在且非 null
if (isset($_SESSION['user_id'])) { ... }
// empty:不存在、null、0、''、false、[] 皆為 true
if (!empty($_POST['email'])) { ... }
function greet(string $name = '訪客'): string {
return "Hello, {$name}";
}
class User {
public string $name = '';
public ?int $age = null;
public array $tags = [];
}
$data = ['id' => 1];
// 正確
$name = $data['name'] ?? '預設';
// 錯誤:直接 $data['name'] 會觸發 Notice
| 環境 | error_reporting | display_errors | log_errors | 備註 |
|---|---|---|---|---|
| 開發 | E_ALL | On | On | 即時看所有提示 |
| 測試/Staging | E_ALL & ~E_DEPRECATED | Off | On | 不顯示用戶,記錄日誌 |
| 生產 | E_ALL & ~E_NOTICE & ~E_DEPRECATED | Off | On | 隱藏細節,記錄關鍵錯誤 |
set_error_handler(function (int $severity, string $message, string $file, int $line) {
if ($severity === E_NOTICE || $severity === E_WARNING) {
throw new ErrorException($message, 0, $severity, $file, $line);
}
return false; // 其他錯誤交給預設處理器
});
try {
echo $undefinedVar; // 現在會拋出 ErrorException
} catch (ErrorException $e) {
// 記錄、回報、優雅降級
error_log($e->getMessage());
}
error_reporting(0) 解決問題:只是掩蓋症狀,真正的邏輯漏洞(如未檢查陣列鍵)仍存在,日後遷移 PHP 版本或框架可能爆發嚴重 Bug。unset() 與 null:unset($var) 讓變數不存在,$var = null 變數存在但值為 null,isset() 行為不同。E_STRICT、E_DEPRECATED:這些提示預告未來版本不相容,開發階段應修正。根治 Notice 的正確順序:
1. 程式碼層面:善用 ??、isset()、預設值、型別宣告,確保變數先定義後使用。
2. 開發環境:開啟 E_ALL 即時發現。
3. 生產環境:display_errors=Off、log_errors=On、error_reporting=E_ALL & ~E_NOTICE & ~E_DEPRECATED。
永遠不要為了省事而關閉錯誤回報,良好的錯誤可見性是維護高品質專案的基石。