配列を値渡しで関数の引数に与えても、関数内での配列への変更は呼び出し元に反映されません。参照渡しで与えると、関数内での配列への変更が呼び出し元にも反映されます。ここでは、その違いを確認しています。
スポンサーリンク
配列を値渡しでパラメータに与える
配列を値渡しでパラメータに与えても、関数内での変更は以下のサンプルのように呼び出し元へは反映されません。
$arr = array(
'item1' => 'value1',
'item2' => 'value2',
'item3' => 'value3',
);
func1($arr); // 関数内の変更が反映されない
var_dump($arr);
// array(3) {
// ["item1"]=> string(6) "value1"
// ["item2"]=> string(6) "value2"
// ["item3"]=> string(6) "value3"
// }
function func1($arr)
{
$arr['item1'] = 'changed value1';
}
配列を参照渡しでパラメータに与える
配列を参照渡しでパラメータに与えた場合、関数内での変更は呼び出し元へ反映されます。
$arr = array(
'item1' => 'value1',
'item2' => 'value2',
'item3' => 'value3',
);
func2($arr); // 関数内の変更が反映される
var_dump($arr);
// array(3) {
// ["item1"]=> string(6) "value1"
// ["item2"]=> string(14) "changed value2"
// ["item3"]=> string(6) "value3"
// }
function func2(&$arr)
{
$arr['item2'] = 'changed value2';
}
このように値渡しと参照渡しの動作の違いを理解したうえで使い分ける必要があります。C 言語のポインタやダブルポインタを理解していれば、これらの違いに悩むことはないでしょう。理解している人はこのページを見ることはないと思いますが。
stdClass の場合
配列の代わりにクラスオブジェクトを使用することも多いと思いますが、ここでは、stdClass の場合の動作を確認してみます。stdClass の場合は、値渡しと参照渡しのいずれの場合でも、関数内の変更が呼び出し元へ反映されます。
$std = new stdClass();
$std->item1 = 'value1';
$std->item2 = 'value2';
func3($std); // 関数内の変更が反映される
func4($std); // 関数内の変更が反映される
var_dump($std);
// object(stdClass)#1 (3) {
// ["item1"]=> string(6) "changed value1"
// ["item2"]=> string(6) "changed value2"
// }
function func3($std)
{
$std->item1 = 'changed value1';
}
function func4(&$std)
{
$std->item2 = 'changed value2';
}