変数の参照 (call by reference)

変数の代入

PHPでは通常、変数の代入はコピー(クローン)が渡されます。
(PHP5ではインスタンスは参照渡し)

PHP:
  1. $var1 = 1;
  2. $var2 = $var1;
  3. $var1 += 10;
  4. $var2 += 20;
  5.  
  6. // VAR1:11 VAR2:21
  7. print "VAR1:$var1 VAR2:$var2";

$var1、$var2、それぞれ独立しています。

参照の代入

参照を代入するには、参照演算子=&を使います。

PHP:
  1. $var1 = 1;
  2. $var2 =& $var1;
  3. $var1 += 10;
  4. $var2 += 20;
  5.  
  6. // VAR1:31 VAR2:31
  7. print "VAR1:$var1 VAR2:$var2";

さっきとは違い、出力文で$var1と$var2が同じである事が分かります。これは、2行目で変数$var1の参照を代入している為です。参照とは変数が持っているアドレス(実際のデータへの住所)の事です。2行目の代入により、$var2が$var1を参照しているのではなく、2つは同じデータを参照しているのです。

PHP:
  1. $var1 = 1;
  2. $var2 =& $var1;
  3. $var1 += 10;
  4. $var2 += 20;
  5.  
  6. // 参照元の変数削除
  7. unset($var1);
  8. // 31
  9. print $var2;

$var1を削除したのに、$var2は残っています。var2はvar1と同じ場所にデータを持つ、別名(エイリアス)の変数と捕らえる事ができます。参照の削除とは、変数名と実際のデータの関係性を破棄することにすぎません。つまり、以下は参照渡しになりません。

PHP:
  1. $var = 100;
  2. $ref =& $var;
  3.  
  4. // エラー
  5. $ref =& 200;
  6.  
  7. function test() {
  8.   return 200;
  9. }
  10. // 無効な参照渡し
  11. $ref =& test();

通常の代入で、わざわざ参照を使う必要はありません。
大きな配列やインスタンスを扱う場面で効果を発揮します。

関数で参照を返す

関数の戻り値を参照にする事もできます。関数名の前に&を付けて、戻り値が参照である事を明示しておきます。返ってきた参照を代入する時も同様に&を付けます。この場合、どちらの&が欠けても参照渡しにはなりません。

PHP:
  1. function & toRef(&$val) {
  2.   return $val;
  3. }
  4.  
  5. // 参照渡し
  6. $val = 'BEFORE';
  7. $ref =& toRef($val);
  8. $ref = 'AFTER';
  9. print $val;// AFTER
  10.  
  11. // コピー渡し
  12. $val = 'BEFORE';
  13. $notref = toRef($val);
  14. $notref = 'AFTER';
  15. print $val;// BEFORE

関数に参照を渡したい時は、必ず定義する時に&を付けておく必要があります。
引数に&をつけて関数を呼ぶ方法は、今後廃止される予定です。

PHP:
  1. // 正
  2. function func(&$arg) {}
  3. func($arg);
  4.  
  5. // 誤
  6. function func($arg) {}
  7. func(&$arg);

インスタンス生成時の注意点

PHP4でコンストラクタ定義で&を付ける必要はありません。ただし、インスタンス生成時にnewがコピーを返すので注意が必要です。

PHP:
  1. class Test {
  2.   var $value = 'foo';
  3.  
  4.   function Test() {
  5.     $GLOBALS["test"] =& $this;
  6.   }
  7.   function set($value) {
  8.     $this->value = $value;
  9.   }
  10.   function display() {
  11.     echo '<br />' . $this->value;
  12.   }
  13. }
  14.  
  15. $obj = new Test();
  16. $obj->set('bar');
  17. $obj->display(); // bar
  18. $test->display();// foo
  19.  
  20. $obj =& new Test();
  21. $obj->set('bar');
  22. $obj->display(); // bar
  23. $test->display();// bar

インスタンスの代入

PHP5からインスタンスの扱いはJAVA同様に参照となります。

PHP:
  1. $obj =& new Class();
  2. // PHP4
  3. $ref_obj =& $obj;// 2つは同じ
  4. $copy_obj = $obj;// 2つは独立
  5.  
  6. // PHP5
  7. $ref_obj = $obj;// 2つは同じ
  8. $copy_obj = clone $obj;// 2つは独立

参考資料

  • Search

Copyright (c) 2004-2008 MT312 All Rights Reserved.
Powered by WordPress ME