そらとぶへび

仕事・プライベートを通しての気づき、JavaやPHP、データベースやサーバの話などこつこつと書いていきます

PHP 参照渡しのキホン

参照渡しはアンパサンド「&」を代入元の変数の「$」の前に付ける。

$a = 'Red';
$b = $a; // 値渡し
$c = &$a; // 参照渡し
echo "代入直後 -> a(元の値):{$a},b(値渡し):{$b},c(参照渡し):{$c}" . PHP_EOL;
$b = 'Blue';

echo "変数b(値渡し)を変更 -> a(元の値):{$a},b(値渡し):{$b},c(参照渡し):{$c}" . PHP_EOL;
$c = 'Green';
echo "変数c(参照渡し)を変更 -> a(元の値):{$a},b(値渡し):{$b},c(参照渡し):{$c}" . PHP_EOL;

実行結果:

代入直後 -> a(元の値):Red,b(値渡し):Red,c(参照渡し):Red
変数b(値渡し)を変更 -> a(元の値):Red,b(値渡し):Blue,c(参照渡し):Red
変数c(参照渡し)を変更 -> a(元の値):Green,b(値渡し):Blue,c(参照渡し):Green

値渡しは、変数$bのみ変わるが、参照渡しの場合、$aが変われば$cも変わる。


参照渡しはforeachでも応用できるので、うまく使いこなせばかなりスマートなコードになる(かもしれない。)

foreach ($array as &$value){
  $value = (ここで代入した値が$arrayに反映される)
}

ちなみに、オブジェクトはデフォルトで参照渡しになる。オブジェクトで値渡しをしたい場合はcloneを使う。

$a = new stdclass(); // オブジェクトとして生成 
$a->test = 'Red'; 

$b = clone $a; //値渡し 
$c = $a; //参照渡し 
echo "代入直後 -> a(元の値):{$a->test},b(値渡し):{$b->test},c(参照渡し):{$c->test}" . PHP_EOL;

// 変数b(値渡し)を変更する 
$b->test = 'Blue'; 
echo "変数b(値渡し)を変更 -> a(元の値):{$a->test},b(値渡し):{$b->test},c(参照渡し):{$c->test}" . PHP_EOL;

// 変数c(参照渡し)を変更する 
$c->test = 'Green'; 
echo "変数c(参照渡し)を変更 -> a(元の値):{$a->test},b(値渡し):{$b->test},c(参照渡し):{$c->test}" . PHP_EOL;

実行結果:

代入直後             -> a(元の値):Red,b(値渡し):Red,c(参照渡し):Red
変数b(値渡し)を変更   -> a(元の値):Red,b(値渡し):Blue,c(参照渡し):Red 
変数c(参照渡し)を変更 -> a(元の値):Green,b(値渡し):Blue,c(参照渡し):Green