基礎

PHPの参照渡し|値渡しとの違いと使い方

PHPで変数を別の変数に代入すると、通常は値のコピーが作られます(値渡し)。一方、&(アンパサンド)を使うと、元の変数と同じデータを参照する変数を作れます。これが参照渡しです。

値渡しと参照渡しの違い

PHP
<?php
// 値渡し(デフォルト)
$a = 10;
$b = $a;     // $a の値をコピー
$b = 20;     // $b を変更しても $a は変わらない
echo "値渡し: a={$a}, b={$b}";
// 出力: 値渡し: a=10, b=20

echo "<br>";

// 参照渡し
$x = 10;
$y = &$x;    // $y は $x と同じデータを参照
$y = 20;     // $y を変更すると $x も変わる
echo "参照渡し: x={$x}, y={$y}";
// 出力: 参照渡し: x=20, y=20
?>
実行結果
値渡し: a=10, b=20
参照渡し: x=20, y=20

値渡しでは変数のコピーが作られるため、片方を変更してもう一方には影響しません。参照渡しでは同じデータを共有するため、どちらを変更しても両方に反映されます。

関数の引数での参照渡し

関数の引数に & を付けると、関数内で元の変数を直接変更できます。

PHP
<?php
// 値渡し(元の変数は変わらない)
function addTenByValue($num) {
    $num += 10;
}

// 参照渡し(元の変数が変わる)
function addTenByReference(&$num) {
    $num += 10;
}

$value = 5;
addTenByValue($value);
echo "値渡し後: {$value}";    // 5(変わらない)
echo "<br>";

addTenByReference($value);
echo "参照渡し後: {$value}";  // 15(変わった)
?>
実行結果
値渡し後: 5
参照渡し後: 15

実用的な例:配列の要素を直接変更

PHP
<?php
$prices = [100, 200, 300, 400, 500];

// foreachで参照渡しを使い、全価格を10%値上げ
foreach ($prices as &$price) {
    $price = (int)($price * 1.1);
}
unset($price); // 参照を解除(重要!)

print_r($prices);
?>
実行結果
Array ( [0] => 110 [1] => 220 [2] => 330 [3] => 440 [4] => 550 )
foreachの参照渡し後はunset()必須

foreachで参照渡しを使った後、unset($price)で参照を解除しないと、ループ後に$priceが最後の要素を参照し続けるため、予期しないバグが発生します。

参照渡しを使うべき場面

参照渡しは便利ですが、コードの可読性が下がるため乱用は避けましょう。大きな配列やオブジェクトを関数内で変更したい場合に使うのが適切です。戻り値で返せるなら、値渡し+returnの方が分かりやすいコードになります。

まとめ

  • 値渡しはコピーを作成、参照渡し(&)は同じデータを共有する
  • 関数の引数に&を付けると、関数内で元の変数を直接変更できる
  • foreachの参照渡し後は必ずunset()で参照を解除する
  • 参照渡しは便利だが乱用せず、必要な場面でのみ使う