PHP 中數組預設為值傳遞(Copy-on-Write 機制)。 函數參數接收數組時,實際上是複製了一份 zval 結構體,但底層數據指向同一個 HashTable。只有發生寫入操作時,才會觸發真正的內存複製(分離)。這與 C/C++ 指針、JavaScript 物件引用有本質區別。
<?php
$arr = ['name' => 'corn', 'age' => '24'];
function test_arr($arr) {
$arr['name'] = 'qqyumidi'; // 修改副本
}
test_arr($arr);
print_r($arr);
// 輸出:Array ( [name] => corn [age] => 24 ) 原數組未變
// JavaScript
let arr = ['corn', '24'];
function test_arr(arr) {
arr[0] = 'qqyumidi'; // 修改原物件
}
test_arr(arr);
console.log(arr); // ["qqyumidi", "24"] 原陣列被修改
PHP 7+ 使用 zval 結構體管理變數:
function test_ref(&$arr) {
$arr['name'] = 'qqyumidi'; // 直接修改原數組
}
$arr = ['name' => 'corn'];
test_ref($arr);
print_r($arr); // Array ( [name] => qqyumidi )
| 場景 | 內存行為 | 效能 |
|---|---|---|
| 只讀傳遞大數組 | 共享內存,無複製 | 極快,O(1) |
| 函數內修改元素 | 觸發分離,複製整個 HashTable | O(n),大數組有開銷 |
| foreach 遍歷修改 | foreach 內部複製數組 | 雙重內存佔用 |
&$arr 明確聲明引用for 迴圈或先複製❌ 「PHP 數組是引用傳遞」
✅ 正確:預設值傳遞,COW 機制使只讀極快,寫入才複製
❌ 「unset($arr) 會釋放內存」
✅ 正確:僅減少引用計數,內存由 GC 回收
理解 PHP 數組的 COW 機制,能寫出高效能、無副作用的代碼。記住:預設值傳遞,需要引用時顯式加 &,大數組只讀零成本,寫入才分離。