PHP 獨有的可變變量(Variable Variables)允許在運行時動態構造變量名,極大地增強了語言的動態性。本文從基礎語法、數組歧義消解、類屬性動態訪問、多級引用,延伸到可變參數(func_get_args)的實戰應用,全方位剖析這一特性。
$a = 'hello';
$$a = 'world'; // 定義 $hello = 'world'
echo "$a ${$a}"; // hello world
echo "$a $hello"; // hello world
// 多級美元符
$Bar = "a";
$Foo = "Bar";
$World = "Foo";
$Hello = "World";
$a = "Hello";
echo $a; // Hello
echo $$a; // World
echo $$$a; // Foo
echo $$$$a; // Bar
echo $$$$$a; // a
// ... 以此類推
$$a[1] 存在兩種解釋:
${$a[1]}:取 $a[1] 的值作為變量名${$a}[1]:取 $a 的值作為變量名,再訪問該變量的下標 1規則:用花括號明確界定優先級,永遠寫 ${$a[1]} 或 ${$a}[1],避免歧義。
class Foo {
public $bar = 'I am bar.';
public $arr = ['I am A.', 'I am B.', 'I am C.'];
public $r = 'I am r.';
}
$foo = new Foo();
$bar = 'bar';
$baz = ['foo', 'bar', 'baz', 'quux'];
echo $foo->$bar; // I am bar.
echo $foo->$baz[1]; // I am bar. ($baz[1] = 'bar')
echo $foo->{'b'.'ar'}; // I am bar. (花括號拼接屬性名)
$arr = 'arr';
echo $foo->$arr[1]; // I am r. (解析為 $foo->{$arr}[1] = $foo->arr[1])
echo $foo->{$arr}[1]; // I am B. (明確先解析 $arr 再取下標)
$obj->{'my-prop'}$obj->{$prefix . $suffix}json_decode($json, true) 或 SimpleXML 產生的非標準屬性名。$nameTypes = ['first', 'last', 'company'];
$name_first = 'John';
$name_last = 'Doe';
$name_company = 'PHP.net';
foreach ($nameTypes as $type) {
print ${"name_$type"} . "\n"; // 動態拼接變量名
}
// 輸出:John / Doe / PHP.net
func_get_args() 實現任意參數函數function sum($a, $b) { return $a + $b; } // 兩個
function sum($a, $b, $c = 0) { return $a+$b+$c; } // 三個(含默認值)
function sum(array $params) {
$total = 0;
foreach ($params as $v) $total += $v;
return $total;
}
sum([1,2,3,4]); // 必須包裝成數組
func_get_args()(優雅)function sum() {
$total = 0;
foreach (func_get_args() as $v) $total += $v;
return $total;
}
echo sum(1, 3, 5); // 9
echo sum(1, 2); // 3
echo sum(1, 2, 3, 4); // 10
| 函數 | 用途 |
|---|---|
func_get_args() | 返回所有實際傳入參數的數組 |
func_num_args() | 返回參數個數 |
func_get_arg($index) | 返回指定索引的參數(0-based) |
function sum($a, $b) {
// 定義前兩個強制參數,其餘走 func_get_args
return array_sum(func_get_args()); // PHP 內置 array_sum 更簡潔
}
arguments 對比func_get_args() 返回副本數組,修改不影響原參數。arguments 是類數組對象,非嚴格模式下修改會映射到對應形參。${$arr[key]} / ${$var}[key] 明確意圖。func_get_args() 實現 sum(...)、log(...) 等通用工具函數,配合 array_sum、vsprintf 等內置函數極其簡潔。function sum(...$nums) 更語義化、性能更好,建議優先使用。深入理解可變變量與可變參數,能讓你在需要極致動態性的場景下游刃有餘,同時保持代碼可維護性。