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

PHP 參考(Reference)深度解析:& 符號、傳址呼叫、物件與複製行為

     編輯:PHP 相關知識

PHP 的參考(Reference)讓多個變數名稱指向同一份記憶體內容,類似 Unix 硬連結。這與 C 指標有本質差異。本文系統講解參考的建立、函數傳遞、回傳、物件行為,並釐清常見誤區。

一、什麼是參考?

參考是符號表別名:$a =& $b 表示 $a 與 $b 指向同一個 zval 容器。修改其中一個,另一個同步變化。

<?php
$a = 100;
$b = &$a; // $b 參考 $a
echo "$a, $b"; // 100, 100
$a++;
echo "$a, $b"; // 101, 101 -- 兩者同步變化
?>

二、函數參考傳遞

在函數參數前加 &,呼叫端對應引數也必須是變數(不可為表達式),函數內修改將影響外部變數。

<?php
function addOne(&$num) {
    $num++;
}
$val = 5;
addOne($val);
echo $val; // 6
?>

三、參考回傳

函數宣告與呼叫端雙雙加 &,回傳變數參考而非複製值。常用於鏈式操作或效能敏感場景。

<?php
class Counter {
    private $value = 0;
    public function &getValue() {
        return $this->value;
    }
}
$obj = new Counter();
$ref = &$obj->getValue(); // 取得參考
$ref = 10;
echo $obj->getValue(); // 10 -- 實際修改了物件屬性
?>

四、參考與物件:關鍵釐清

「物件預設傳遞是參考」是錯誤觀念。 PHP 5+ 物件變數存放的是「物件標識符」,傳遞時複製的是標識符(像傳值),但指向同一物件實體。真正的參考需顯式加 &。

<?php
class A { public $v = 1; }
$a = new A();
$b = $a;        // 複製標識符,$a/$b 指向同一物件
$b->v = 2;
echo $a->v; // 2 -- 修改了同一物件

$c = new A();
$a = $c;        // $a 現在指向新物件,$b 仍指向舊物件
$a->v = 3;
echo $b->v; // 2 -- $b 未受影響

// 真正參考物件變數
$d = new A();
$e = &$d;       // $e 是 $d 的別名
$d = new A();   // $d 指向新物件,$e 也跟著指向新物件
?>

五、複製時寫入(Copy-on-Write)機制

PHP 內核採用 COW 優化:$b = $a 時不複製記憶體,僅增加引用計數;當任一變數發生寫入操作,才真正分離複製。參考(&)則強制共享同一 zval,寫入直接影響所有別名。

六、unset() 與參考

unset($b) 僅銷毀別名 $b,不影響 $a 的內容(不同於 C 的 free(ptr) 會導致懸空指標)。

七、實務建議

  • 大型陣列傳遞給函數時,若需修改原陣列,使用參考傳遞避免複製開銷
  • 避免過度使用參考回傳,Zend 引擎已優化大多數複製場景
  • 物件屬性、陣列元素可單獨建立參考:$ref = &$arr['key']
  • foreach ($arr as &$v) 迴圈結束後建議 unset($v) 釋放參考,防止後續誤用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved