PHP 引用(&)讓多個變量名指向同一內容,類似 Unix 硬鏈接。本文系統講解引用的本質、賦值/傳遞/返回三大操作、unset 行為、foreach 陷阱、全局引用、對象引用,以及底層「寫時拷貝」機制。
$a =& $b;
$a 和 $b 完全等價,指向同一內存區域。不是 $a 指向 $b(C 指針風格)。
$a = 5; $b =& $a; $b = 10; echo $a; // 10
function foo(&$var) { $var++; }
$a = 5; foo($a); echo $a; // 6
// 僅函數定義需 &,調用時不加(PHP 5.4+ 調用加 & 會警告)
可引用傳遞:變量、new 實例、函數引用返回。不可:表達式、字面量、非引用返回的函數調用。
class Foo { public $value = 42; public function &getValue() { return $this->value; } }
$obj = new Foo;
$myVal = &$obj->getValue(); // $myVal 引用 $obj->value
$obj->value = 2; echo $myVal; // 2
// 必須:聲明 &function、返回變量、調用處 &賦值,三處皆需 &
返回表達式(如 return ($this->value))會觸發 E_NOTICE 並失效。
$a = 1; $b =& $a; unset($a); // $b 仍為 1,內容未銷毀
$ref = 0; $row =& $ref;
foreach (array(1,2,3) as $row) { /* ... */ }
echo $ref; // 3(最後一個元素值),因 $row 是引用,循環修改了 $ref
建議:foreach ($arr as $k => &$v) 結束後 unset($v) 斷開引用。
global $var; // 等價於 $var =& $GLOBALS['var'];
function test($useGlobal) {
global $var1, $var2;
if (!$useGlobal) $var2 =& $var1; // 僅函數內可見
else $GLOBALS['var2'] =& $var1; // 全局可見
}
$obj2 = $obj1 共享同一實例。$obj2 =& $obj1 則是真正引用,unset($obj1) 不影響 $obj2,但 $obj1 = null 會導致 $obj2 也為 null(引用計數歸零)。$this 永遠是調用對象的引用。$a = "ABC"; $b = $a; // 此時 $a、$b 指向同一內存
$a = "EFG"; // 發生寫操作,Zend 為 $b 複製一份 "ABC",重新申請內存
function(&$arr) 避免隱式拷貝。function(&$arr)。&。$obj = null(引用計數歸零觸發 GC),而非 unset($obj)(僅斷開變量名)。