PHP 引用(&)是讓多個變量指向同一內存地址的機制。理解其在變量、函數參數/返回值、對象三大場景下的行為差異,是寫出正確、高效代碼的關鍵。
$a = 'ABC';
$b = &$a; // $b 是 $a 的別名
$b = 'EFG';
echo $a; // EFG —— 修改任一變量,另一變量同步變化
取消引用:unset($b) 僅斷開 $b 的綁定,$a 保留值;$b = null 則會將共享內存設為 null,導致 $a 也變 null。
function add100(&$num) { $num += 100; }
$val = 1;
add100($val);
echo $val; // 101
add100(1) 會報錯)。&$param 表示該參數為引用,內部修改直接影響外部變量。function &getCounter() {
static $count = 0;
return $count; // 返回靜態變量的引用
}
$a = getCounter(); // 普通調用:返回值複製,$a=1
$a = 5;
$a = getCounter(); // 仍返回 2(靜態變量自增)
$b = &getCounter(); // 引用調用:$b 與靜態 $count 綁定
$b = 5; // 修改靜態 $count 為 5
$b = getCounter(); // 返回 6(靜態變量基於 5 自增)
規則:只有 $var = &func() 才建立引用綁定;$var = func() 永遠是值複製,即使函數聲明了 &。
class Foo { public $bar = 1; }
$a = new Foo; // $a 持有對象句柄 #1
$b = $a; // $b 複製句柄 #1,指向同一對象
$b->bar = 2;
echo $a->bar; // 2 —— 修改 $b 影響 $a
$a = new Foo; // $a 重新指向新對象 #2,$b 仍指向 #1
echo $b->bar; // 2
$b = &$a; // 顯式引用:$b 成為 $a 的別名
$a = new Foo; // $a 指向 #3,$b 也指向 #3
$a->bar = 5;
echo $b->bar; // 5
核心結論:
$b = $a)是**句柄複製**,非深拷貝,雙方共享同一對象實例。clone 才產生獨立副本(淺拷貝,屬性若為對象仍共享)。$b = &$a)讓變量本身綁定,重新賦值時雙方同步指向新對象。foreach ($arr as &$v) { ... } unset($v); **必須**在循環後 unset($v),否則 $v 保留對最後元素的引用,後續誤用會修改數組尾部。function foo(&$a = 1) 語法錯誤;預設值只能用於值傳遞。& 反而可能破壞引擎優化、降低可讀性。僅在**確需修改外部變量**、**大數組/字符串避免複製**(極少數場景)時使用。掌握引用機制本質,不再為「為什麼我的數組被莫名修改」而困擾,代碼更健壯、意圖更清晰。