PHP 參考讓兩個變數指向相同的內容(記憶體位置),而非複製值。不同於 C 指標存放記憶體位址,PHP 參考是符號表別名,操作任一變數皆影響同一資料。
<?php
$a = 'ABC';
$b =& $a; // $b 參考 $a
echo $a; // ABC
echo $b; // ABC
$b = 'EFG';
echo $a; // EFG($a 也變了)
echo $b; // EFG
<?php
function add100(&$num) {
$num += 100;
}
$val = 1;
add100($val);
echo $val; // 101
// 錯誤示範:add100(1); // 嚴格模式下報錯:不能將字面值傳址
<?php
function &getCounter() {
static $count = 0;
$count++;
return $count;
}
$val1 = getCounter(); // 1,普通賦值
$val1 = 5;
$val2 = getCounter(); // 2,$count 未受 $val1 影響
$ref =& getCounter(); // 3,參考回傳
$ref = 5;
$ref2 =& getCounter(); // 6,$count 變為 5,再 +1 = 6
關鍵:$ref =& getCounter() 才建立參考連結,$val = getCounter() 僅複製回傳值。
<?php
class A { public $prop = 'ABC'; }
$obj1 = new A();
$obj2 = $obj1; // PHP 5+ 物件賦值預設即為參考行為
$obj2->prop = 'DEF';
echo $obj1->prop; // DEF
// 若需真正複製,使用 clone
$obj3 = clone $obj1;
$obj3->prop = 'GHI';
echo $obj1->prop; // DEF(未受影響)
&$obj = null 解除參考,配合 GC 釋放記憶體global $var 等同 $var =& $GLOBALS['var']<?php
$a = 'ABC'; // 內容 'ABC' 參考計數=1
$b = $a; // $b 指向同一 'ABC',參考計數=2(未複製)
$a = 'EFG'; // 發生寫入,Zend 引擎為 $b 複製一份 'ABC',再修改 $a 為 'EFG'
這意味著唯讀操作不複製記憶體,只有寫入時才分離,極大提升效能。
<?php
$a = 1;
$b =& $a;
unset($a); // 僅解除 $a 綁定,$b 仍保有值 1
echo $b; // 1
&clone