参照とは何ですか?
PHP における参照とは、同じ変数の内容に異なる名前でアクセスすることを意味します。これは C ポインターとは異なり、参照はシンボル テーブルのエイリアスです。 PHP では変数名と変数の内容が異なるため、同じ内容でも異なる名前が付けられることに注意してください。最も近い類似点は、Unix のファイル名とファイル自体です。変数名はディレクトリ エントリであり、変数の内容はファイル自体です。参照は、Unix ファイル システムのハードリンクと考えることができます。
リファレンスの役割
PHP のリファレンスでは、2 つの変数が同じコンテンツを指すことができます。つまり、これを実行すると:
<?php $a =& $b; ?>
これは、$a と $b が同じ変数を指すことを意味します。
注:
$a と $b はここではまったく同じです。$a が $b を指しているわけではなく、$a と $b が同じ場所を指しているのです。
注:
参照を持つ配列がコピーされた場合、その値は逆参照されません。配列値を関数に渡す場合も同様です。
注:
未定義の変数が参照によって割り当てられた場合、参照パラメータによって渡された場合、または参照によって返された場合、変数は自動的に作成されます。
例 #1 未定義変数への参照の使用
<?php function foo(&$var) { } foo($a); // $a is "created" and assigned to 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) ?>
同じ構文を、参照を返す関数と新しい演算子 (PHP 4.0.4 以降) で使用できます。
<?php $bar =& new fooclass(); $foo =& find_var($bar); ?>
PHP 5 以降、 new は自動的に参照を返すため、ここでの =& の使用は廃止され、E_STRICT レベルのメッセージが生成されます。
注:
& 演算子を使用しないと、オブジェクトのコピーが生成されます。クラスで $this を使用すると、クラスの現在のインスタンスに適用されます。 & なしの代入はインスタンス (オブジェクトなど) をコピーし、$this はそのコピーに作用しますが、必ずしも望ましい結果になるとは限りません。パフォーマンスとメモリ消費の問題のため、通常は 1 つのインスタンスのみで作業する必要があります。
@new などの @ 演算子を使用してコンストラクター内のエラー メッセージを抑制することは可能ですが、&new ステートメントを使用する場合は効果がありません。これは Zend エンジンの制限であり、解析エラーが発生します。
警告 関数内でグローバルとして宣言された変数に参照が割り当てられている場合、その参照は関数内でのみ表示されます。これは、$GLOBALS 配列を使用することで回避できます。
例 #2 関数内でグローバル変数を参照する
<?php $var1 = "Example variable"; $var2 = ""; function global_references($use_globals) { global $var1, $var2; if (!$use_globals) { $var2 =& $var1; // visible only inside the function } else { $GLOBALS["var2"] =& $var1; // visible also in global context } } global_references(false); echo "var2 is set to '$var2'\n"; // var2 is set to '' global_references(true); echo "var2 is set to '$var2'\n"; // var2 is set to 'Example variable' ?>
global $var; を $var =& $GLOBALS['var']; の省略形として扱います。したがって、他の参照を $var に代入しても、ローカル変数の参照が変更されるだけです。
注:
foreach ステートメントで参照を含む変数に値を代入すると、参照されるオブジェクトも変更されます。
例 #3 foreach ステートメントによる参照
<?php $ref = 0; $row =& $ref; foreach (array(1, 2, 3) as $row) { // do something } echo $ref; // 3 - last element of the iterated array ?>
参照が行う 2 番目のことは、参照によって変数を渡すことです。これは、関数内にローカル変数を作成し、その変数が呼び出しスコープ内の同じコンテンツを参照することによって実現されます。例:
<?php function foo(&$var) { $var++; } $a=5; foo($a); ?>
は $a を 6 に変更します。これは、foo 関数の変数 $var が $a が指すのと同じ内容を指しているためです。
参照が行う 3 番目のことは、参照を返すことです。
参照とは何なのか
前に述べたように、参照はポインタではありません。これは、次の構成では期待される効果が得られないことを意味します:
<?php function foo(&$var) { $var =& $GLOBALS["baz"]; } foo($bar); ?>
これにより、関数の呼び出し時に foo 関数の $var 変数が $bar にバインドされますが、その後 $GLOBALS[" baz に再バインドされます"] その上。関数 foo には変数 $bar が存在しないため ($var として表されますが、$var には変数の内容のみが含まれ、呼び出しはありません)、参照メカニズムを通じて $bar を関数呼び出しスコープ内の別の変数にバインドすることはできません。シンボル テーブルの名前と値のバインディング)。参照リターンを使用して、関数によって選択された変数を参照できます。