PHP参照渡しまとめ
RAMとアドレス
変数はコンピュータの中のメモリRAMに値が保存される。メモリにはアドレスが有ってどのアドレスどんな値が入っているかを管理している。
値渡し
メモリーの違うアドレスに値をコピーして保存する方法。元の変数と別のアドレスで管理される。
参照渡し
メモリーの同じアドレスを参照する方法。メモリーの同じアドレスを使うので元変数でも渡した後の変数のどちらかでも変更すると同じ値になる。
PHPでは
関数の引数は値渡しになる。
オブジェクトはインスタンスIDが渡されるため参照渡しの様に振る舞う。ある関数にオブジェクトを渡して、関数内でオブジェクトを更新したら呼び出し元に戻ったときにも関数内で更新された状態が戻ってくる。
引数、変数の先頭に&を付けると参照渡しになる。
<?php
//------------------------------------
$name1 = 'Hikakin';
$name2 = &$name1; // ← name2はname1と同じアドレスの変数を参照する
$name3 = $name1; // ← name3はname1と違うアドレスに変数を保存する
$name1 = 'Seikin'; // name1 を Seikinにする
echo $name2."\n"; // Seikin 参照渡しでname1と同じアドレスを参照しているのでSeikinに変わっている
echo $name3."\n"; // Hikakin 値渡しでコピーした値を持っているのでHikakinのまま
//------------------------------------
$val1 = 'abc';
function funcOne($val) // ← 値渡し 別アドレスに値をコピー
{
$val = 'xyz';
}
funcOne($val1);
echo $val1 . "\n"; // abc
//------------------------------------
$val2 = 'abc';
function funcTwo(&$val) // ← 参照渡し caller側と同じアドレスの変数を参照
{
$val = 'xyz';
}
funcTwo($val2);
echo $val2 . "\n"; // xyz
//------------------------------------
$list1 = ['a','b','c'];
function funcThree($val) { // ←Arrayも値渡し。別アドレスにコピーされている
$val = ['x','y','z'];
}
funcThree($list1);
var_dump($list1); // 'a','b','c'
//------------------------------------
$list2 = ['a','b','c'];
function funcFour(&$val) {
$val = ['x','y','z'];
}
funcFour($list2);
var_dump($list2); // 'x','y','z'
//------------------------------------
$obj = new stdClass; // ←オブジェクトID#1が作成される
$obj->name = 'Hikaru';
function funcFive($obj) { // ←オブジェクトはオブジェクトを管理するIDが渡される
$obj->name = 'Repezen'; // ← オブジェクトID#1 に対して操作するので 参照渡しの様に振る舞う
}
funcFive($obj);
var_dump($obj); // 'Repezen ←レペゼンが侵食していく