底層機制:PHP 的「裸詞」解析規則
當數組索引使用 不帶引號的標識符(如 `$arr[key]`)時,PHP 按以下順序解析:
- 嘗試作為常量查找(`defined('key')`)
- 若常量不存在,發出
E_NOTICE(PHP 7.2+ 棄用警告),**自動當作字符串 `'key'` 處理**為什麼會發生這個 Bug?
- 定義了常量 `WEBHOST = 'blog'`
- `$wso[WEBHOST]` → 解析常量 `WEBHOST` → 值為 `'blog'`
- 實際訪問 `$wso['blog']` → 返回 `'www.weixiaodeyu.com'`
實際危害場景
// 配置文件 define('STATUS_ENABLE', 1); define('STATUS_DISABLE', 0); $data = [ 'STATUS_ENABLE' => '啟用', 'STATUS_DISABLE' => '禁用', 1 => '數字鍵1', 0 => '數字鍵0', ]; // 業務代碼 $status = 1; // 來自數據庫 echo $data[$status]; // 正常:'數字鍵1' echo $data[STATUS_ENABLE]; // 正常:'啟用'(常量值 1) // 重構時誤改為 echo $data['STATUS_ENABLE']; // 正常:'啟用' // 但若常量名與數組鍵名衝突且值不同 define('TYPE_A', 'type_b'); // 常量值指向另一鍵 $arr = ['type_a' => 'A', 'type_b' => 'B']; echo $arr[TYPE_A]; // 訪問 $arr['type_b'] → 'B'(極難排查)最佳實踐:強制加引號
| 寫法 | 推薦 | 說明 |
|---|---|---|
$arr['key'] | ✅ 強烈推薦 | 明確字符串鍵,無歧義,性能最優(無常量查找) |
$arr["key"] | ✅ 推薦 | 雙引號同樣明確,支持變量插值(索引中罕用) |
$arr[key] | ❌ 禁止 | 隱式常量查找,PHP 8.1+ 拋出 Error,極易產生 Bug |
數組字符串索引永遠加引號 是鐵律。這不僅是代碼規範,更是防止「常量污染索引」這類極難排查 Bug 的關鍵防線。現代 PHP 版本已強制要求,請立即清理存量代碼中的裸詞索引。