PHP 中的引用(在變量、函數、對象前加 & 符號)意味著「不同名稱訪問同一內容」。這與 C 語言指針本質不同:C 指針存儲內存地址,PHP 引用由 Zend 引擎實現,採用「寫時拷貝」機制——除非發生寫操作,否則多個變量共享同一內存區塊。本文系統梳理引用的四大核心場景、常見誤區與性能優化要點。
<?php
$a = "ABC";
$b = &$a; // $a 與 $b 指向同一內存
$b = "EFG"; // 觸發寫時拷貝,$a 同步變為 EFG
?>
關鍵點:$a =& $b 表示雙向綁定,而非單向指向。unset 僅斷開變量名與內容的綁定,不銷毀內容本身。
<?php
function test(&$a) { $a += 100; }
$b = 1;
test($b); // $b 變為 101
// test(1); // 錯誤:只能傳遞變量,不能傳常量
?>
注意:調用時 test($b) 前不加 &;但 call_user_func_array('a', array(&$c)) 中必須顯式加 &。
<?php
function &test() {
static $b = 0;
return $b;
}
$a = test(); // 普通賦值,修改 $a 不影響 $b
$a =& test(); // 引用返回,$a 與 $b 共享內存
$a = 5; // $b 同步變為 5
?>
PHP 規定:只有 $a =& test() 才建立引用綁定,適用於對象鏈式操作與靜態資源復用。
<?php
class A { public $abc = "ABC"; }
$b = new A();
$c = $b; // PHP 5+ 等同於 $c =& $b
$b->abc = "DEF"; // $c->abc 同步變為 DEF
// 深拷貝需用:$c = clone $b;
?>
PHP 4 需 $b =& new A() 節省內存;PHP 5+ new 自動返回引用,使用 =& 會觸發 E_STRICT 警告。
global $var 等價於 $var =& $GLOBALS['var'],函數內重新綁定僅影響局部引用。foreach ($arr as &$v) 循環結束後 $v 仍引用最後一元素,建議循環後 unset($v)。$arr2 = $arr1 會複製引用關係,導致多變量指向同一內存,修改一處影響全局。Zend 引擎對大數組採用寫時拷貝優化:值傳遞不觸發拷貝,引用傳遞卻會預判「可能寫入」而強制拷貝。實測證明,不必要地加 & 導致性能下降 30%+。原則:大數組唯讀傳值,確需修改才傳引用;對象 PHP 5+ 默認引用無需額外操作。
&,配合 $var = null 手動釋放大對象。&,否則勿用。clone。正確理解 PHP 引用機制,是寫出高性能、低 Bug 代碼的關鍵門檻。