升級 PHP 5.4+ 或調整 error_reporting 後,大量舊代碼會拋出 Notice: Undefined index 警告。這不影響程序邏輯但污染日誌、暴露路徑信息。本文提供從配置層面、代碼層面、架構層面三個維度的徹底解決方案。
PHP Notice: Undefined index: page in /var/www/html/read.php on line 56
// 對應代碼:$page = $_GET['page']; // 直接訪問不存在的鍵
; php.ini
; 生產環境推薦:報告所有錯誤但不包含 Notice 和 Strict
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; 開發環境建議:全開啟,盡早發現問題
; error_reporting = E_ALL
; 關鍵:關閉 display_errors,開啟 log_errors
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
優點:零代碼修改,立竿見影。
缺點:掩蓋潛在邏輯缺陷(如拼寫錯誤的變量名),不利於代碼質量提升。
// 錯誤
$page = $_GET['page'];
// 正確
$page = isset($_GET['page']) ? $_GET['page'] : 1; // 默認值 1
// 或 PHP 7+ 空合併運算符
$page = $_GET['page'] ?? 1;
function get($array, $key, $default = null) {
return isset($array[$key]) ? $array[$key] : $default;
}
// 使用
$page = get($_GET, 'page', 1);
$name = get($_POST, 'username', '');
$config = get($GLOBALS['config'], 'db.host', 'localhost');
$defaults = array('page' => 1, 'size' => 20, 'sort' => 'desc');
$params = array_merge($defaults, $_GET); // 後者覆蓋前者
// $params['page'] 必定存在
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, array(
'options' => array('default' => 1, 'min_range' => 1)
));
$request->input('page', 1)、Symfony $request->query->get('page', 1)、ThinkPHP input('get.page/d', 1) 內置默認值與驗證。$_GET、$_POST、$_REQUEST,補全缺失鍵、類型轉換、XSS 過濾。| 場景 | 推薦方案 | 備註 |
|---|---|---|
| 維護老舊項目、無時間重構 | 方案一 (php.ini) | 臨時過渡,需制定計劃逐步修正代碼 |
| 新項目、模塊開發 | 方案二 (?? / isset / filter_input) | 養成習慣,代碼審查強制要求 |
| 使用現代框架 | 方案三 (Request 對象) | 框架已封裝,切勿直接用超全局變量 |
| 團隊協作、長期維護 | 方案二 + 方案三 + 靜態分析 | 建立編碼規範,CI 阻擋 Notice 級問題 |
@$_GET['page'] 性能差、難調試、掩蓋真實問題。headers already sent,檢查文件編碼(UTF-8 無 BOM)、頂部空行。從「屏蔽報錯」轉向「預防缺陷」,才是解決 Undefined index 的專業態度。建立防御性編程習慣,配合現代框架工具,讓代碼在嚴格模式下依然穩健運行。