PHP のリファレンスにより二つの変数が同じ内容を参照することが可能です。 つまり、以下のようなものを実行した場合です。
<?php
$a =& $b;
?>
注意: ここで、$a と $b は完全に 同じで、$a が $b を 指しているわけではなく、その逆でもありません。$a と $b は同じ場所を指しているのです。
注意: リファレンスを含む配列をコピーする際に、そのリファレンスが解消される ことはありません。配列を関数に値渡しする場合も同様です。
注意: 未定義の変数のリファレンスに対して代入したり 渡したり返したりすると、そこで変数が作成されます。
例1 未定義の変数のリファレンスの使用
<?php
function foo(&$var) { }
foo($a); // $a が作成され、null が代入されます
$b = array();
foo($b['b']);
var_dump(array_key_exists('b', $b)); // bool(true)
$c = new StdClass;
foo($c->d);
var_dump(property_exists($c, 'd')); // bool(true)
?>
リファレンスを返す関数や new 演算子でも 同じ構文が使用可能です(PHP 4.0.4 以降)。
<?php
$bar =& new fooclass();
$foo =& find_var($bar);
?>
注意: & 演算子を使用しない場合は、オブジェクトのコピーが 作成されます。クラスの内部で $this を使用した場合、 それはクラスの現在のインスタンスに対する操作を表します。 & のない代入はインスタンス(オブジェクト)のコピーを 行い、$this はそのコピーに対する操作を表します。 これはお望みの動作と異なるかもしれません。パフォーマンスやメモリ使用量の 観点から、常に単一のインスタンスに対して操作を行いたくなることもあるでしょう。
コンストラクタ内で @new のようにして @ 演算子を使用すると、あらゆるエラーの表示を 見えなくすることが可能ですが、 &new を使用する場合にはこの機能は動作しません。 Zend Engine の仕様により、これはパースエラーとなります。
関数の内部で global 宣言された変数にリファレンスを 代入すると、そのリファレンスは関数の内部でのみ参照可能となります。 これを避けるには、$GLOBALS 配列を使用します。
例2 関数内でのグローバル変数の参照
<?php
$var1 = "Example variable";
$var2 = "";
function global_references($use_globals)
{
global $var1, $var2;
if (!$use_globals) {
$var2 =& $var1; // 関数の内部でのみ参照可能
} else {
$GLOBALS["var2"] =& $var1; // 関数の外部でも参照可能
}
}
global_references(false);
echo "var2 の値は '$var2'\n"; // var2 の値は ''
global_references(true);
echo "var2 の値は '$var2'\n"; // var2 の値は 'Example variable'
?>
注意: foreach ステートメント の内部でリファレンス変数に値を代入すると、リファレンスも変更されます。
例3 リファレンスと foreach ステートメント
<?php
$ref = 0;
$row =& $ref;
foreach (array(1, 2, 3) as $row) {
// 何かを実行します
}
echo $ref; // 3 - 配列の最後の要素
?>
リファレンスの第 2 の使用法は、変数のリファレンス渡しです。この場合、 関数でローカル変数が作成され、コール側の変数が、それと同じ内容への リファレンスとなります。例を示します。
<?php
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
?>
リファレンスの第 3 の使用法は、 リファレンスによる返り値 です。