你知道在函式的參數前面加上「&」就可以達成 Pass by reference 吧?
但你知道在 PHP 裡面,
Object 是不管怎麼傳都是 Pass by reference 嗎?
舉例來說,
底下這段程式碼執行完之後,$obj->key
會是 value 還是 12345678 呢?
<?php
function assign($obj, $key, $value)
{
$obj->{$key} = $value;
}
$obj = new stdClass;
$obj->key = 'value';
assign($obj, 'key', '12345678');
print_r($obj);
大家只要把這程式碼拿去執行就知道答案了!
根據 PHP 官方的說法,
說 Object 這東西預設就是 Pass by reference 是不完全對的說法。
怎麼說呢?
從 PHP 5 之後,每當你在 new 一個 Object 的時候,
其實你宣告的變數得到的並非 Object 本身,而是得到對 Object 的參考。
所以**「參考」傳到哪都是參考**,只不過 PHP 可以用它來找到參考指向的 Object。
也因此,如果改寫上面的範例,
讓 assign 函式在修改資料之後把 Object 回傳,
並比較原 Object,及修改後的 Object,
會發現它們其實還是一樣的。
<?php
function assign($obj, $key, $value)
{
$obj->{$key} = $value;
return $obj;
}
$obj = new stdClass;
$obj->key = 'value';
$alteredObj = assign($obj, 'key', '12345678');
echo $obj->key === $alteredObj->key ? 'true' : 'false';
除非對傳入 Object 執行 clone,PHP 才知道你要的並非傳入 Object 的參考,而是它的複本:
<?php
function assign($obj, $key, $value)
{
$obj = clone $obj;
$obj->{$key} = $value;
return $obj;
}
$obj = new stdClass;
$obj->key = 'value';
$alteredObj = assign($obj, 'key', '12345678');
echo $obj->key === $alteredObj->key ? 'true' : 'false';
希望今天的內容可以幫助到你,
讓你能避免浪費許多踩雷及 debug 的時間~