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

PHP 函數參數傳遞機制深度解析:值傳遞、引用傳遞與對象行為

     編輯:PHP 綜合知識

參數傳遞的三種面相:值、引用、對象句柄

PHP 函數參數傳遞看似簡單,實則蘊含「值傳遞」、「引用傳遞」、「對象句柄傳遞」三種語義差異。理解它們對於編寫可預測、無副作用的代碼至關重要。本文通過代碼實驗逐一驗證行為差異。

1. 值傳遞:預設行為,副本隔離

<?php
function exam($var1) {
    $var1++;
    echo "In Exam: $var1<br/>";
}

$var1 = 1;
echo "$var1<br/>";  // 1
exam($var1);       // In Exam: 2
echo "$var1<br/>";  // 1  ← 外部變量未改變
?>

結論:函數接收變量副本,內部修改不影響外部原變量。適用於純計算、不需回寫場景。

2. 引用傳遞:& 符號打通內外

<?php
function exam(&$var1) {
    $var1++;
    echo "In Exam: $var1<br/>";
}

$var1 = 1;
echo "$var1<br/>";  // 1
exam($var1);       // In Exam: 2
echo "$var1<br/>";  // 2  ← 外部變量同步修改
?>

結論:函數簽名加 &,實參與形參綁定同一記憶體地址,雙向同步。慎用:增加耦合、降低可讀性,僅在需明確修改外部變量時使用(如大數組去重、避免拷貝開銷)。

3. 可選參數與預設值

<?php
function values($price, $tax = 0) {  // 建議給預設值而非空字串
    $price += $price * $tax;
    echo "Total Price: $price<br/>";
}

values(100, 0.25); // Total Price: 125
values(100);       // Total Price: 100
?>

注意:原碼 $tax="" 導致字串參與運算隱式轉型為 0,雖結果相同但語意不清,建議直接 $tax = 0 或 $tax = null 配合 ?? 運算符。

4. 對象傳遞:句柄複製,指向同一實體

<?php
class Obj {
    public $name, $age, $gender;
    public function __construct($name, $age, $gender) {
        $this->name = $name; $this->age = $age; $this->gender = $gender;
    }
    public function show_info() {
        echo "{$this->name} {$this->age} {$this->gender}<br/>";
    }
}

function grow($obj) {
    $obj->age++;  // 修改對象屬性
}

$obj = new Obj("Mr. Zhan", 12, "male");
$obj->show_info(); // Mr. Zhan 12 male
grow($obj);
$obj->show_info(); // Mr. Zhan 13 male  ← 外部對象被修改
grow($obj);
$obj->show_info(); // Mr. Zhan 14 male
?>

核心原理圖解

傳遞方式函數簽名內部修改參數變量本身內部修改對象屬性/元素
值傳遞 (標量/陣列)func($x)不影響外部不影響外部 (陣列為副本)
引用傳遞func(&$x)影響外部影響外部
對象傳遞func($obj)不影響外部 (重新賦值 $obj=new Obj 只斷開局部綁定)影響外部 (句柄指向同一實例)

最佳實踐建議

  1. 預設用值傳遞:純函數風格,無副作用,易測試、易並行。
  2. 對象傳遞即引用語義:不需加 & 即可修改對象狀態;若需在函數內替換整個對象實例並反映外部,才加 &。
  3. 大數組考慮引用:避免拷貝開銷,但需文檔標註「會修改原數組」。
  4. PHP 7.1+ 類型聲明:function grow(Obj $obj): void 靜態分析可捕獲誤用。

掌握參數傳遞語義,是從「能跑通」進階到「寫得穩」的關鍵一步。下次定義函數時,請先問自己:這個參數,我希望函數內部能改變外部嗎?

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