PHP 支援可變變數名稱 ($$var) 與可變屬性名稱 ($obj->$prop),但在陣列與物件屬性鏈中會產生解析歧義,需用大括號明確指定結構。
<?php
$a = 'hello';
$$a = 'world'; // 等同 $hello = 'world';
echo "$a ${$a}"; // hello world
echo "$a $hello"; // hello world
<?php
$arr = ['foo', 'bar', 'baz'];
$key = 1;
// 情境 1:取得 $arr[1] 的值作為變數名
${$arr[1]} = 'value1'; // 正確:${$arr[1]} 先解析 $arr[1]='bar',再建立 $bar
// 錯誤寫法:$$arr[1] 會被解析為 ${$arr}[1] (先取 $arr 再取索引 1)
// 情境 2:$arr 為變數名,取其索引 1
${$arr}[1] = 'value2'; // 正確:${$arr} 解析為 $arr 陣列,再取 [1]
<?php
class Foo {
public $bar = 'I am bar.';
public $baz = ['foo', 'bar', 'baz', 'quux'];
}
$obj = new Foo();
$prop = 'bar';
$propArr = 'baz';
echo $obj->$prop . "\n"; // I am bar. (正常)
echo $obj->$propArr[1] . "\n"; // I am bar. (正確:$propArr='baz',取 $obj->baz[1])
// 若寫成 $obj->$baz[1] 且 $baz 為陣列,會先解析 $baz[1] 再取屬性,易發生錯誤
// 建議永遠用大括號明確:
echo $obj->{$propArr}[1] . "\n"; // 明確:先解析屬性名 $propArr,再取索引
$_GET, $_SESSION 等) 不可 用於可變變數:${$_GET} 會報錯。$this 為特殊變數,不可 作為可變變數名稱。{$obj->{$prop}} 消除歧義。property_exists()、isset() 防禦性檢查。