3

Pimple は、silex フレームワークで使用される php の単純な依存性注入コンテナーです。ここでソースコードを調べていました。ドキュメントでは、関数offsetGetは依存関係コンテナーにアタッチされているクラスの同じインスタンスを返します。関連するコードoffsetGetは次のとおりです。

public function offsetGet($id)
{
    if (!isset($this->keys[$id])) {
        throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
    }

    if (
        isset($this->raw[$id])
        || !is_object($this->values[$id])
        || isset($this->protected[$this->values[$id]])
        || !method_exists($this->values[$id], '__invoke')
    ) {
        return $this->values[$id];
    }

    if (isset($this->factories[$this->values[$id]])) {
        return $this->values[$id]($this);
    }

    $this->frozen[$id] = true;
    $this->raw[$id] = $this->values[$id];

    return $this->values[$id] = $this->values[$id]($this);
 }

ここで、オブジェクトがfactoriesObject Store( SplObjectStoragetype) にある場合、id $id を持つクラスの新しいインスタンスを返します。次に、最後のリターンで再び$this->values[$id]オブジェクトの新しいインスタンスに設定され、その新しいインスタンスが返されます。

return $this->values[$id] = $this->values[$id]($this).

これは私が理解できない行です。この行はoffsetGet、同じ $id の異なる呼び出しに対して同じインスタンスを返すことになっています。毎回新しいインスタンスを返しませんか? 私を助けてください。いろいろ試しましたがわかりません。

4

1 に答える 1

3

pimple のソース コードを調べたところ、オブジェクトがインスタンス化されて に保持される$this->values[$id]と、次の の呼び出しでoffsetGet2 番目の状態から戻ることがわかりましたif。つまり、このif条件:

if (
    isset($this->raw[$id])
    || !is_object($this->values[$id])
    || isset($this->protected[$this->values[$id]])
    || !method_exists($this->values[$id], '__invoke')
) {
    return $this->values[$id];
}

単体テストを見てみると、マジックメソッドのないオブジェクトは__invoke共有できることがわかりました。オブジェクトにマジック メソッドがある場合__invoke(つまり、オブジェクトを関数として扱うことができる場合)、毎回新しいインスタンスが返されます。したがって、上記の if ステートメントの 1 番目、2 番目、3 番目の条件が false を返すことがわかります。しかし、4 番目の条件は true を$this->values[$id]返すため、毎回同じインスタンスが返されます。

于 2013-12-11T09:35:14.643 に答える