首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 變量引用、函數引用與對象引用深度解析

     編輯:PHP 相關知識

PHP 引用(&)是讓多個變量指向同一內存地址的機制。理解其在變量、函數參數/返回值、對象三大場景下的行為差異,是寫出正確、高效代碼的關鍵。

1. 變量引用:別名綁定

$a = 'ABC';
$b = &$a; // $b 是 $a 的別名
$b = 'EFG';
echo $a; // EFG —— 修改任一變量,另一變量同步變化

取消引用:unset($b) 僅斷開 $b 的綁定,$a 保留值;$b = null 則會將共享內存設為 null,導致 $a 也變 null。

2. 函數引用傳參(傳址調用)

function add100(&$num) { $num += 100; }
$val = 1;
add100($val);
echo $val; // 101
  • 調用時**必須**傳變量,不可傳常量/表達式(add100(1) 會報錯)。
  • 函數簽名 &$param 表示該參數為引用,內部修改直接影響外部變量。

3. 函數引用返回:返回變量別名而非值

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() 永遠是值複製,即使函數聲明了 &。

4. 對象引用(PHP 5+):句柄複製而非深拷貝

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

核心結論:

  1. 對象賦值($b = $a)是**句柄複製**,非深拷貝,雙方共享同一對象實例。
  2. clone 才產生獨立副本(淺拷貝,屬性若為對象仍共享)。
  3. 顯式引用($b = &$a)讓變量本身綁定,重新賦值時雙方同步指向新對象。

常見陷阱與最佳實踐

  • foreach 循環引用殘留:foreach ($arr as &$v) { ... } unset($v); **必須**在循環後 unset($v),否則 $v 保留對最後元素的引用,後續誤用會修改數組尾部。
  • 函數參數預設值不能用引用:function foo(&$a = 1) 語法錯誤;預設值只能用於值傳遞。
  • 避免濫用引用優化:PHP 7+ 內部優化(Copy-on-Write、引用計數)已極致,手動加 & 反而可能破壞引擎優化、降低可讀性。僅在**確需修改外部變量**、**大數組/字符串避免複製**(極少數場景)時使用。

掌握引用機制本質,不再為「為什麼我的數組被莫名修改」而困擾,代碼更健壯、意圖更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved