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

深入理解 PHP 變量、函數與物件的引用機制

     編輯:PHP 相關知識

在 PHP 中,引用意味著不同的變量名稱指向同一個變量內容。這與 C 語言的指標有本質區別:C 指標存儲的是變量在內存中的地址,而 PHP 的引用是符號表層面的別名綁定。理解這一機制對編寫高效、穩定的 PHP 代碼至關重要。

變量引用

PHP 允許兩個變量指向同一內容。使用 & 符號建立引用關係:

<?php
$a = "ABC";
$b = &$a;
echo $a; // 輸出: ABC
echo $b; // 輸出: ABC
$b = "EFG";
echo $a; // 輸出: EFG (因為 $a 和 $b 指向同一內容)
echo $b; // 輸出: EFG
?>

此時 $a 和 $b 在符號表中指向同一個 zval 結構,修改任一變量都會影響另一個。

函數傳址調用

函數參數前加 & 可實現傳址調用,函數內部修改參數會影響外部變量:

<?php
function test(&$a) {
    $a = $a + 100;
}
$b = 1;
echo $b; // 輸出 1
test($b);
echo "<br>";
echo $b; // 輸出 101
?>

注意:test(1) 這樣直接傳遞字面量會報錯,因為無法對字面量建立引用。

函數引用返回

PHP 規定只有使用 $a = &test() 才能獲得函數的引用返回:

<?php
function &test() {
    static $b = 0;
    $b = $b + 1;
    echo $b;
    return $b;
}

$a = test();   // 輸出 1,普通調用,$a 只是值拷貝
$a = 5;
$a = test();   // 輸出 2,仍不影響靜態變量 $b

$a = &test();  // 輸出 3,引用返回,$a 與 $b 綁定
$a = 5;
$a = test();   // 輸出 6,$b 的值已被改為 5,再遞增變 6
?>

引用返回的本質是將返回變量的內存地址與接收變量綁定,類似 $a = &$b。此特性常用於物件模式中。

物件引用

PHP 5 中物件預設以引用方式傳遞和賦值:

<?php
class A {
    var $abc = "ABC";
}
$b = new A;
$c = $b;        // 相當於 $c = &$b
echo $b->abc;   // ABC
echo $c->abc;   // ABC
$b->abc = "DEF";
echo $c->abc;   // DEF (因為 $b 和 $c 指向同一物件)
?>

若需建立物件副本且不受原物件影響,需使用 __clone 魔術方法實現深拷貝。

引用的實際應用場景

  • 大型程式中,多變量引用同一物件,需手動清除時建議用 & 方式,再用 $var = null 釋放。
  • 大數組傳遞時使用引用可節省內存。

取消引用與特殊機制

unset 僅斷開變量名與內容的綁定,不銷毀內容本身:

<?php
$a = 1;
$b = & $a;
unset($a); // $b 仍存在,值為 1
?>

global $var 實際建立到 $GLOBALS["var"] 的引用,unset $var 不會銷毀全局變量。物件方法中 $this 永遠是調用該方法物件的引用。

底層原理:寫時拷貝

PHP 內核採用「寫時拷貝」機制:

  1. $a = "ABC"; $b = $a; 此時兩者指向同一內存地址,不佔用額外內存。
  2. 當 $a = "EFG"; 發生寫操作,Zend 核心自動為 $b 複製一份數據,重新分配內存。

這種機制在不發生寫入時極大節省了內存開銷。

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