2

次のように仮定します。

private $array = array(/*really big multi-dimensional array*/);

public function &func1($specific_large_sub_array_key)
{
     return $this->array[$specific_large_sub_array_key]
}

public function func2()
{
    $specificArray = &$this->func1(1);

    $this->func3($specificArray);
}


public function func3($specificArray)
{
    /* do stuff here*/
}

私の質問はこれです:

func3 が $specificArray を参照渡ししないように指定していない場合、PHP は func2 内で func3 を呼び出したときに $specificArray のコピーを作成しますか? または、PHP は参照を保持し、自動的に伝播しますか?

つまり、これは...

public function func3($specificArray)
{
    unset($specificArray[234]);
}

...$配列に影響しますか?

ありがとうございました

この例は非常に単純化されていることに注意してください。

4

2 に答える 2

5

PHP は、変数とコピーをどのように処理するかに関して非常にインテリジェントです。

次の例を見てください。

// Allocate one variable with content 'Hello'
$var     = 'Hello';

この時点で、Zend Engine は文字列変数を Hello という内容で表現しています。

これを行う場合:

$varCopy = $var;

2 つの独立変数 ($var$varCopy) がありますが、それらの内容は同じであるため、内容はメモリ内の 1 つの場所にしか存在しません (基本的に、真のコピーはまだ作成されていません)。この時点で、2 つの変数はシンボル テーブル内の同じ値 (Hello) を参照します。2 つの変数のいずれかが変更されると、コンテンツのみがコピーされます。これと同じロジックが、2 つのコピーから任意の数のコピーに対して機能します。

簡単に言えば、PHP は、変数や配列の値をコピーする必要がない場合はコピーしないほど賢いのです。

詳細については、PHP マニュアルの参照カウントの基本ページを参照してください。最後に、配列に固有の例も示しています。

便利な関数として、PHP が使用しているメモリの量を表示できるmemory_get_usageがあります。これを使用して、配列の複数のコピーを渡すときにメモリ使用量がほとんど変化しないという事実を追跡できます。これは、マニュアルの参照カウントの基本セクションで概説されているポイントを証明するのに役立ちます。

PHP がどのように動作するかについてすべての詳細を知る必要はありませんが、PHP が参照を作成および管理する方法が優れていることに注意してください。

編集:

実際の質問に直接答えるには、いいえ、func3参照で渡さなくてもPHPは配列のコピーを作成しません。参照カウントの基本セクションで説明されているように参照を使用するため、気にせずに値で渡すことができます。

ただし、unset を呼び出した場合、unset した値は配列のローカル コピーからのみ削除されるため、参照によって関数に渡さない限り、最終的にはソース配列から削除されません。しかし、それを値渡ししても、巨大な配列全体のまったく新しいコピーが作成されるわけではありません。コピーから 1 つの値を削除しても、削除したエントリを差し引いたまったく新しいコピーは作成されません (最初の配列とまったく同じ参照を持つ 2 番目の配列があるだけですが、削除されたエントリへの 1 つの参照が欠落しています)。

于 2012-04-17T00:16:26.323 に答える
1

複数行のコメントはできないので、答えとして:

return &$this->array[$specific_large_sub_array_key]
       ^

しかし、あなたの質問にも答えてください:

つまり、これは... [...] ...$array に影響しますか?

単純明快: いいえ。理由: 別名 (参照) ではなく、別の変数です。

于 2012-04-17T00:15:17.330 に答える