$run_return_data = [];
$ret = $this->handleData($event_req_info, $run_return_data);
public function handleData($event_req_info, &$run_return_data): array
{$run_return_data = [ //使用引用變量返回數據'shop_id' => $shop_id,'request_id' => $request_id,];
}
在你的 PHP 代碼中,能夠在調用方獲取到 $run_return_data
的值,是因為你在函數參數中使用了 引用傳遞(&$run_return_data
)。這種行為與 Go 語言的指針傳遞有本質區別,主要源于兩種語言在參數傳遞機制上的設計差異。
為什么 PHP 中能獲取到修改后的值?
PHP 中,函數參數默認是 值傳遞(即傳遞變量的副本),但通過在參數前添加 &
符號,可以顯式指定為 引用傳遞。此時:
- 函數內部對
$run_return_data
的修改(包括直接賦值一個新數組),本質上是對 原變量內存地址的內容 進行修改。 - 調用方的
$run_return_data
與函數內部的$run_return_data
指向 同一塊內存,因此修改會直接反映到外部。
你的代碼中,handleData
方法通過 &$run_return_data
聲明了引用傳遞,所以內部對 $run_return_data
的重新賦值($run_return_data = [...]
)會直接改變外部變量的值。
Go 與 PHP 在參數傳遞上的核心區別
特性 | Go 語言 | PHP 語言 |
---|---|---|
默認傳遞方式 | 所有參數均為 值傳遞(包括指針本身也是值傳遞)。 | 默認是 值傳遞,但可通過 & 顯式指定引用傳遞。 |
指針/引用的含義 | 指針是一個存儲內存地址的變量(類似“地址標簽”)。 函數接收指針時,接收的是指針的 副本(仍指向原數據)。 | 引用是變量的“別名”,與原變量共享同一塊內存。 函數接收引用時,直接操作原變量的內存。 |
對參數重新賦值的影響 | 若在函數內對指針參數 重新賦值(如 p = &newObj ),只會修改指針副本的指向,不影響外部原始指針。只有修改指針 指向的內容(如 p.Field = 123 ),才會影響外部。 | 若通過引用傳遞(¶m ),函數內對參數 重新賦值(如 $param = [...] ),會直接修改外部變量的值。 |
舉例對比
1. Go 語言(指針傳遞)
type Data struct {Value int
}func modify(p *Data) {// 錯誤:重新賦值指針副本,外部不受影響p = &Data{Value: 200}// 正確:修改指針指向的內容,外部會受影響// p.Value = 200
}func main() {d := &Data{Value: 100}modify(d)fmt.Println(d.Value) // 輸出 100(因為函數內是重新賦值指針副本)
}
2. PHP 語言(引用傳遞)
function modify(&$data) {// 直接重新賦值,外部會受影響(因為是引用傳遞)$data = ['value' => 200];
}$d = ['value' => 100];
modify($d);
echo $d['value']; // 輸出 200(引用傳遞導致外部變量被修改)
總結
- PHP 的引用傳遞 更接近“變量別名”,函數內對參數的任何修改(包括重新賦值)都會直接影響外部。
- Go 的指針傳遞 本質是“地址的副本”,只有修改指針指向的內容(而非指針本身),才會影響外部。
這就是為什么你在 PHP 中通過引用傳遞能獲取到修改后的值,而 Go 中若錯誤地對指針本身重新賦值則無法生效。