【6日でできるPHP入門】参照渡し

 複数の関数を組み合わせて開発していると、関数内で変数の値を書き換えたい場面が出てきます。PHP では引数を「値渡し(デフォルト)」と「参照渡し(& を付ける)」の 2 通りで受け取ることができ、後者を使うと呼び出し元の変数をそのまま書き換えられます。ここでは参照渡しの仕組みと使いどころを、比較表とサンプルコードを交えて解説します。

1.引数の渡し方を理解しよう

1.1. 値渡しとは

用語説明
値渡し実引数の値を「コピー」して関数に渡す方法。関数内で変更しても元の変数は変化しない。

1.2. 参照渡しとは

用語説明
参照渡し実引数が格納されているメモリアドレスを渡す方法。関数内の変更が呼び出し元へ反映される。
&参照を示す演算子。引数宣言時に付ける。

1.3. 構文上のポイント

function 関数名(&$param, $other){ ... } // & を付けた引数だけが参照渡し
  • 省略すると自動的に 値渡し
  • 参照渡しは挙動が直感と異なるので、意図が明確なときだけ使うのが推奨

2.サンプルで動きを確認

2.1. 値渡し vs 参照渡しの比較

ファイル名: lesson47_1.php

<?php
// 値渡し:職務を変更しても呼び出し元に影響しない
function set_job_value($role){
    $role = "研究者"; // コピーを書き換えるだけ
}

// 参照渡し:呼び出し元の変数を書き換える
function set_job_ref(&$role){
    $role = "起業家"; // 元の変数が変わる
}

// 変数の初期値
$kenichi_job = "技術者";
$yuko_job    = "技術者";

// 関数呼び出し
set_job_value($kenichi_job); // 値渡し
set_job_ref($yuko_job);      // 参照渡し

// 結果表示
echo "健一の職務は{$kenichi_job}です。<br>";
echo "優子の職務は{$yuko_job}です。<br>";
?>

実行結果

プログラム解説

動作関連命令
3set_job_value 宣言(値渡し)function
4ローカル変数 $role 書き換え=
8set_job_ref 宣言(参照渡し)&
9参照先を書き換え → 呼び出し元反映=
19値渡し呼び出しset_job_value()
20参照渡し呼び出しset_job_ref()
24-25結果出力echo

2.2. 参照渡しで配列を一括更新

ファイル名: lesson47_2.php

<?php
function add_suffix(array &$names, string $suffix = "さん"){
    foreach($names as &$n){
        $n .= $suffix;
    }
}

$list = ["田中", "佐藤"];
add_suffix($list);
print_r($list); // Array ( [0] => 田中さん [1] => 佐藤さん )
?>

実行結果

  • 内部ループでも &$n を付けて要素を直接変更
  • 参照渡しは多重ループ時に副作用が広がりやすいため要注意

3.参照渡しの注意点

3.1. 予期せぬ副作用

シチュエーション起こり得る問題
関数内で変数を再代入呼び出し元も変わり、デバッグが困難
再帰や多段関数呼び出し。どこで変更されたか追跡が難しい。

3.2. 使いどころ

  • 大きな配列・オブジェクトを頻繁に渡すときのパフォーマンス向上
  • 戻り値が複数あるときに、引数を“出力パラメータ”として使う場合
function calc_stats(array $data, &$sum, &$avg){
    $sum = array_sum($data);
    $avg = $sum / count($data);
}

まとめ

  • PHP の引数はデフォルトで 値渡し& を付けると 参照渡しになり、関数内での変更が呼び出し元へ反映される。
  • メリットはメモリ効率と多値返却の容易さ、デメリットは副作用によるバグ増加。
  • ルール: 意図が明確・影響範囲が小さい場合のみ参照渡しを採用する。