変数の参照渡し
参照渡し「&」で
- 違う名前の変数を参照できる
参照渡しとは
変数には変数を代入する事が可能です。つまり、
- $a = 3;
- $b = $a;
のような代入に関係してきます。さてこういった代入の場合、元の変数$aの値を変更すると、$aを代入された$bの値はどうなるでしょうか。見たほうが早いのでサンプルスクリプトを載せて説明代わりにします。
- $a = 3;
- $b = $a; // $bには$aの値を代入
- $a = 5; // $aの値を変更して・・・
- echo $b; // $aを代入されている$bを出力
出力結果
$bには「$a」を代入しているにもかかわらず、$aの値を変更しても$bの値は元の「3」を保持したままです。これは、PHPが$aと$bを違う変数として扱っているためです。PHPの内部的な話になりますが、$aと$bは「同じ値を持つっていうだけの違う変数」という扱いで別々の領域に保存されます。これを参照渡しというものを使う事によって、PHP内部で$aと$bを「違う名前を持つ同じ変数」として扱えるようにできます。つまり、参照渡しを使うと$aの値を変えたら$bの値も変わるという事です。
参照渡しを使うにはアンパサンド「&」を使います。「&」記号を代入する方の変数の「$」記号の前に付ければいいだけです。
参照渡しサンプル
- $a = 3;
- $b = $a; // $bは通常の代入
- $c = &$a; // $cは参照渡しで代入
- $a = 5; // 元の変数$aを変更すると・・・
- echo '通常の代入($b):' . $b . "<br />\n";
- echo '参照渡しで代入($c):' . $c . "<br />\n";
- $b = 10; // 通常代入された変数$bを変更すると・・・
- echo '$b変更後の元の変数($a):' . $a . "<br />\n";
- $c = 7; // 参照渡しされた変数$cを変更すると・・・
- echo '$c変更後の元の変数($a):' . $a;
出力結果
参照渡しで代入($c):5
$b変更後の元の変数($a):5
$c変更後の元の変数($a):7
参照渡しを使う事で元の変数$aを変えると、$cの値も自動的に変わるようになりました。
PHP5での参照渡し
PHP5のオブジェクトでは参照渡しがデフォルトの設定のようです。
オブジェクトなら関係ないや~~と思われた方もいると思いますが、この機会に少し技術的な話を追加しておきます。PHP内部で値というものがどのように渡されているいるか記述しておきます。
- $b = $a;
という代入方法はPHP4までは$bに$aの値のコピーが渡されますが、PHP5からは$bが$aそのものの変数空間を参照している(つまりは参照渡し)事になります。
PHP4までは「同じ値を持つってだけで違う変数として扱われる」と書きましたが、$b=$aの時点で、$bには$aの「値のコピー」が渡され、$aと$bはコピーされた値を持つまったく別の変数空間を持っている事になります。変数空間というのは、よーはPHPが変数を格納してる場所・・・というか部屋とか・・・ま、メモリ上の領域の事ですが、つまり$aと$bはまったく別の部屋に違う変数として格納される訳です。
PHP5からは参照渡しがデフォルト、つまりアンパサンド「&」を付けなくても「勝手に参照渡し」なのです。参照渡しでは$b=$aの時点で、値のコピーは行われず、アドレスが渡されます。アドレスというのは上記の変数空間へのパスみたいなもんだと考えてもらっていいです。つまり参照渡しはPHP内部的に「違う名前の変数が同じ変数空間を利用できる」という技術ですが、値をコピーして別の領域に保存するわけではなく、同じ領域に違う名前でアクセスできる分メモリの節約だとか、高速化だとかが計られるのでしょう。
さて、PHP5でPHP4と同様、「値のコピー」を渡したい場合は
- __clone; //アンダーバー「_」が2つ連続でついてます。
というメソッドを使います。
- $b = $a -> __clone();
これでPHPと同様、値を「コピー」します。
この参照渡しですが、便利なだけに結構使ってる場合が多く、PHP4からPHP5に移行する時にスクリプトの書き換えに困ります。PHP4から5への移行を考えてる人は覚悟しておいて下さい。PHP4を使用する状況は大分減っては来ましたが、なるべくバージョン互換考えたスクリプトを組んでみて下さい。





