在 PHP 開發中,變量賦值機制是基礎卻關鍵的知識點。本文系統梳理值賦值與引用賦值的核心差異,並深度剖析 foreach 循環中引用賦值導致的經典陷阱,助你避開隱形 Bug。
值賦值會將表達式的值完整複製給目標變量,雙方互不影響:
<?php
$number = 15;
$age = 20;
$sum = 12 + "15"; // $sum = 27(字符串自動轉型)
// 數組值賦值示例
$lang[] = "php";
$lang[] = "html";
$lang[] = "css";
// 結果:0=>php, 1=>html, 2=>css
?>
關鍵特徵:修改新變量不影響原變量,記憶體中存在兩份獨立數據。
使用 & 符號建立引用,多個變量指向同一內存地址:
<?php
$val1 = "hello";
$val2 = & $val1; // 或寫作 $val2 = &$val1
$val2 = "goodby";
echo '$val1 is ' . $val1 . "<br>"; // 輸出:goodby
echo '$val2 is ' . $val2 . "<br>"; // 輸出:goodby
?>
核心規則:任一變量修改,所有引用該地址的變量同步變化。
這是 PHP 開發者最易踩的坑之一:
<?php
$a = array(
'a' => 'aa',
'b' => 'bb',
'c' => 'cc',
);
// 第一輪:引用遍歷
foreach ($a as &$v) {
// 僅建立引用,無實際操作
}
print_r($a);
// 輸出:Array ( [a] => aa [b] => bb [c] => cc ) 看似正常
// 第二輪:值遍歷
foreach ($a as $v) {
// 隱含賦值操作!
}
print_r($a);
// 驚人輸出:Array ( [a] => aa [b] => bb [c] => bb )
?>
foreach 結束後,$v 仍保持對 $a['c'] 的引用foreach 以值模式遍歷,但每次迭代實際執行 $v = $a[key] 賦值$v 仍引用 $a['c'],每次賦值實際修改的是 $a['c']$a['c'] 覆寫為 $a['c'] 原值(已被上輪改為 bb)<?php
// 方案 1:循環後立即銷毀引用(推薦)
foreach ($arr as &$v) { /* ... */ }
unset($v); // 斷開引用連接
// 方案 2:避免同一變量名混用引用/值模式
foreach ($arr as &$valueRef) { /* 引用操作 */ }
foreach ($arr as $valueCopy) { /* 值操作 */ }
// 方案 3:PHP 7.0+ 使用引用遍歷語法糖
foreach ($arr as $key => &$value) { /* 安全引用 */ }
?>
理解底層內存模型,養成 unset($v) 習慣,能有效規避 90% 的引用相關 Bug。