これは非常に興味深い質問であることがわかりました。私はこの1時間半、PHPとそれが参照を処理する方法について読みました(私を始めたリンクをありがとうTim Cooper)。
あなたの質問に答えるには、そうです-関数を呼び出すときは、そのような参照を使用することをお勧めします。参照を使用することで、使用するリソースが少なくなります。参照変数の「コピーオンライト」はありません。ここにいくつかの証拠があります:
<?php
function noref_nowrite($var_a){
echo '<h3>NOT Using a Reference/Not Changing Data</h3>';
echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
echo '<p>'. debug_zval_dump($var_a) .'</p>';
echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
function noref_write($var_a){
$var_a++;
echo '<h3>NOT Using a Reference/Changing Data</h3>';
echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
echo '<p>'. debug_zval_dump($var_a) .'</p>';
echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
function ref_nowrite(&$var_a){
echo '<h3>Using a Reference/Not Changing Data</h3>';
echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
echo '<p>'. debug_zval_dump($var_a) .'</p>';
echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
function ref_write(&$var_a){
$var_a++;
echo '<h3>Using a Reference/Changing Data</h3>';
echo '<p>'. xdebug_debug_zval('var_a') .'</p>';
echo '<p>'. debug_zval_dump($var_a) .'</p>';
echo '<p>$var_a = '. $var_a .' and $GLOBALS[a] = '. $GLOBALS['a'] .'</p>';
}
$a = 5;
noref_nowrite($a);
noref_write($a);
ref_nowrite($a);
ref_write($a);
?>
上記のコードをコピーしてPHPページに貼り付けて実行すると、次のように表示されます。
NOT Using a Reference/Not Changing Data
var_a: (refcount=3, is_ref=0)=5
long(5) refcount(4)
$var_a = 5 and $GLOBALS[a] = 5
NOT Using a Reference/Changing Data
var_a: (refcount=1, is_ref=0)=6
long(6) refcount(2)
$var_a = 6 and $GLOBALS[a] = 5
Using a Reference/Not Changing Data
var_a: (refcount=3, is_ref=1)=5
long(5) refcount(1)
$var_a = 5 and $GLOBALS[a] = 5
Using a Reference/Changing Data
var_a: (refcount=3, is_ref=1)=6
long(6) refcount(1)
$var_a = 6 and $GLOBALS[a] = 6
つまり、ここにあるのは4つの基本的なテストです。グローバル変数($ a)を作成し、それに値5を割り当てます。
noref_nowrite関数を呼び出すと、XDebugは3つの参照をカウントし、PHPの組み込み関数は4をカウントすることがわかります。興味深いことに、PHPはこれを最適化するため、PHPは$var_aを$GLOBALS ['a']に参照するため、内部的にはref_nowrite関数を呼び出すのと同じです。 。
noref_write関数を呼び出すと、refcountが1(または、PHPの組み込み関数を見ると2)に低下していることがわかります。なんで?これは、「コピーオンライト」の問題が発生する場所だからです。$ var_aをインクリメントするまで、PHPは内部で$var_aを$aへの参照として使用していましたが、値を変更すると、PHPに変数のコピーを作成させて、インクリメントできるようにしました。そのため、その時点で$var_aは$aへの参照ではなくなり、代わりに独自のデータを参照するように変更されました。
ref_nowrite関数はあいまいな結果を示します。それだけを見ると、何も証明できません。ただし、ref_write関数は、XDebugが参照変数(is_ref = 1)を処理していることを示し、最も重要なことは、$ var_aをインクリメントした後、グローバル変数$aの値も変更されたことを示しています。これは$var_aと$GLOBALS['a']は間違いなくメモリ内の同じ場所を指しています。つまり、$ var_aを変更しても、「コピーオンライト」の状況はトリガーされませんでした。参照を処理しているため、トリガーされるべきではありません。
これをいじって自分を納得させてください。
PHP変数が参照/参照されているかどうかを検出する(ircmaxellにはよく考えられた答えがあると思いました)
http://us2.php.net/debug-zval-dump
XDebugのドキュメント: http: //xdebug.org/docs/display
PHPリファレンスの機能:http://us3.php.net/manual/en/language.references.whatdo.php
PHP参照カウントの基本:http://us3.php.net/manual/en/features.gc.refcounting-basics.php