PHP 獨特的「變數變數」語法允許以一個變數的**值**作為另一個變數的**名稱** (即 $$var)。本文從基礎語法、運作原理、陣列/物件屬性動態存取,延伸至實務應用場景 (如表單批次處理、配置映射)、常見陷阱與最佳實務建議。
"; // 輸出: ic echo $$var_name . "
"; // 輸出: This is Simon (等同 $ic) echo $ic . "
"; // 輸出: This is Simon ?>
核心概念:$$var_name 解析為 ${$var_name} → ${"ic"} → $ic。PHP 先取得 $var_name 的值 "ic",再尋找名為 $ic 的變數。
$arr = ['user' => ['name' => 'John', 'age' => 30]];
$field = 'name';
$key = 'user';
echo $arr[$key][$field]; // 正常寫法
echo $arr[$key][$field]; // 動態鍵名:$field 變數值作為鍵
// 複雜情況:鍵名本身也是動態
$keys = ['user', 'profile', 'settings'];
$target = 'name';
$data = $arr;
foreach ($keys as $k) {
if (isset($data[$k])) $data = $data[$k];
}
echo $data[$target] ?? 'Not found';
class User {
public $name = 'Alice';
public $email = 'alice@example.com';
}
$user = new User();
$prop = 'email';
echo $user->$prop; // 輸出: alice@example.com
// 動態方法呼叫
$method = 'getName';
if (method_exists($user, $method)) echo $user->$method();
$a = 'b'; $b = 'c'; $c = 'd'; $d = 'Final Value'; echo $$$$a; // 解析:$$$$a → $$$b → $$c → $d → 'Final Value' // 實務極少用,僅展示機制
| 場景 | 說明 | 代碼模式 |
|---|---|---|
| 表單欄位批次驗證/賦值 | 將 $_POST 鍵名動態映射到物件屬性 | $obj->$key = $_POST[$key]; | 配置陣列動態展開 | 以前綴區分模組配置,動態建立變數 | $$prefix . '_' . $key = $val; |
| 模板引擎變數注入 | 將資料陣列鍵值轉為模板可用變數 | foreach($data as $k=>$v) $$k = $v; |
| 動態類別實例化 | 根據字串建立對應類別物件 | $obj = new $className($args); |
| 多語系鍵值映射 | 根據語系代碼動態選取翻譯陣列 | $lang = 'en'; $trans = ${"trans_$lang"}; |
$$_GET['var']),可能導致變數覆蓋、代碼注入。**嚴禁直接使用未過濾輸入作為變數名。**${$arr['key']} 需用大括號明確界定,$$arr['key'] 會被解析為 ($$arr)['key'] (先動態取 $arr 再取鍵)。var_dump($GLOBALS) 或 get_defined_vars() 可檢視所有動態建立的變數。$data['ic'] = 'value'; $data[$var_name] — 最通用、安全、可序列化。$obj->{$prop} — 結合型別提示、存取控制、魔術方法 __get/__set。動態變數是 PHP 靈活性的體現,但「大權在握、大責在肩」。掌握其機制後,應將其視為**特定場景的精準工具**而非通用慣用語,優先選擇結構化資料結構提升代碼可維護性。