3

このコードが期待どおりに機能しないのはなぜですか? Test(&$array) 関数内で、ref パラメータをグローバル $array1 に設定しましたが、これは機能しませんでした。

$array1 = array();
$array2 = array();

function Test(&$array)
{
    global    $array1;
    $array = &$array1;

    $array['inside'] = 'inside';

}

//関数による設定:

Test($array2); 
$array2['test1'] = 'test1';

var_dump($array1); //array('inside' => 'inside') ** WHERE IS THE 'test1'  key? **
var_dump($array2); //array('test1' => 'test1')   ** WHERE IS THE 'inside' key? **

//関数なしで設定:

$array2 = &$array1;
$array2['test2'] = 'test2';

var_dump($array1); //array('inside' => 'inside', 'test2' => 'test2') ** FINE **
var_dump($array2); //array('inside' => 'inside', 'test2' => 'test2') ** FINE **

編集:

$array を $array1 を指すように変更した場合、$array1 が関数の外側に 'inside' => 'inside' 値を持つことは明らかです。$array2['test1'] = 'test1' を設定した場合、この $array1 も変更しないのはなぜですか? 関数内の前に「リンク」されています!

4

2 に答える 2

5

関数内で行う場合$array = &$array1;、ローカル変数の値を変更します$array

以前はへの参照がありまし$array2たが、現在はへの参照が含まれています$array1。したがって、を変更する$arrayと、を変更することになります$array1

于 2013-01-14T20:33:26.100 に答える
2

PHP での参照についての私の理解と、そのコードが期待どおりに機能しない理由を次に示します (間違っている場合は、だれか私に飛びついてください。私は頻繁に参照を使用します! また、私が説明したよりも優れた用語があると確信しています「識別子」と「値」を呼んでいますが、どちらの概念にも「変数」を使用することを避けたかっただけです。)

  • たくさんの変数識別子 (データを取得する方法) とたくさんの変数値 (データが実際にある場所) があります。
  • 通常の変数の場合、1 つの値を指す識別子は 1 つだけです。たとえば$foo、特定の値を参照します-数値、文字列などを保持できるPHPの内部のどこかにあるバケット
  • 通常の代入演算子、たとえば を使用するたびに$foo = 42、PHP はポイントされている値を探して更新します。したがって、識別子$fooは変更されていませんが、それがポイントしている値は変更されていません。
  • たとえば などの参照を割り当てると、$bar =& $foo実際には PHP に識別子自体を変更するように指示していることになります。したがって、$bar$fooは同じ値を指す 2 つの異なる識別子です。$foo = -1両方とも$bar = -2この値に書き込みます。どの名前を付けても、その値を参照しています。
  • ここまでは順調ですね。しかし、今書くとどうなります$foo =& $bobか?ではなく識別子を変更しているため、 と同じ値を指し始めますが、元の場所にとどまります。だから今、変えても何の違いもありません。$foo$bob$bar$foo$bar
  • 関数への参照によってパラメーターを渡す場合も、同様のことが起こります。したがって、問題の例では、行は と呼ばれる関数内にTest($array2)新しい識別子$arrayを作成しますが、それは と同じを指します$array2。ただし、関数内には、$array = &$array1その新しい識別子 ( $array) を取り、それを と同じ値にポイントする行があります$array1$array2まだ指している古い値は変更されていません。
  • このように機能する状況は他にもあります。たとえば、globalandstaticキーワードは、既存の値を指す追加の識別子を作成します。と書くfunction foo() { global $foo; $bar = 2; $foo =& $bar; }と、呼び出された関数のローカル識別子だけがの値$fooを指すように更新されます。グローバル識別子 (グローバル スコープにいる場合は$barとも呼ばれます) は、依然として元の値を指しています。$foo

PHP の通常の値の参照システムには、常に1 レベルの間接参照が含まれます。たとえば、C の場合のように、ポインターへのポインターをポインターへのポインターを作成することはできません。

唯一のトリッキーなケースはオブジェクトであり、多くの言語と同様に、独自の余分なレベルの間接性を持っています。一方、 fromの値を$foo = 42; $bar = $foo;表すデータをにコピーし、オブジェクト ポインタをコピーします。したがって、とはまだ別々のを持っていますが、 のような割り当てはに影響を与えず、両方とも同じオブジェクトを変更することになります。42$foo$bar$foo = new stdClass; $bar = $foo$foo$bar$foo = 42$bar$foo->a = 1;$bar->a = 1

于 2013-01-14T21:50:23.323 に答える