There are three basic operations performed using references: assigning by reference, passing by reference, and returning by reference. This section will give an introduction to these operations, with links to further reading.
In the first of these, PHP references allow you to make two variables refer to the same content. Meaning, when you do:
<?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 5.0.0 未満まで)。
<?php
$foo =& find_var($bar);
?>
関数の内部で 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 - 配列の最後の要素
?>
厳密にリファレンスでの代入をしなくても、 array() で作成した式は、配列の要素の先頭に & を追加したのと同じような動作をします。たとえば、次のようになります。
<?php
$a = 1;
$b = array(2, 3);
$arr = array(&$a, &$b[0], &$b[1]);
$arr[0]++; $arr[1]++; $arr[2]++;
/* $a == 2, $b == array(3, 4); */
?>
しかし、配列の内部のリファレンスは危険もあるということに気をつけましょう。 通常の (リファレンスではない) 代入の右辺にリファレンスを使っても 左辺はリファレンスには変わりませんが、配列の内部のリファレンスは通常の代入のままとなります。 これは、関数をコールする際に配列をリファレンスで渡すときも同じです。 たとえば、次のようになります。
<?php
/* スカラー変数への代入 */
$a = 1;
$b =& $a;
$c = $b;
$c = 7; // $c はリファレンスではないので $a や $b の値は変わりません
/* 配列変数への代入 */
$arr = array(1);
$a =& $arr[0]; // $a および $arr[0] は同じリファレンスセットになります
$arr2 = $arr; // これは、リファレンス代入ではありません!
$arr2[0]++;
/* $a == 2, $arr == array(2) */
/* $arr の内容は、たとえリファレンスでなくても変わります! */
?>
リファレンスの第 2 の使用法は、変数のリファレンス渡しです。この場合、 関数でローカル変数が作成され、コール側の変数が、それと同じ内容への リファレンスとなります。例を示します。
<?php
function foo(&$var)
{
$var++;
}
$a=5;
foo($a);
?>
リファレンスの第 3 の使用法は、 リファレンスによる返り値 です。