1

ここに私が持っている2つのサンプルクラスがあります:

/** @ODM\Document */
class Product implements JsonSerializable{

  /** @ODM\String */
  protected $some_property;

  /** @ODM\EmbedMany */
  protected $attributes;

  public function jsonSerialize(){
    $o = new StdClass();
    $o->property = $this->some_property;
    $o->attributes = $this->attributes;
    return $o;
  }
}

/** @ODM\EmbeddedDocument */
class Attribute implements JsonSerializable{

  /** @ODM\String */
  protected $some_property;

  public function jsonSerialize(){
    $o = new StdClass();
    $o->property = $this->some_property;
    return $o;
  }
}

私のコードでは、Product のインスタンスを作成し、いくつかのプロセスが に Attribute インスタンスの配列を作成します$product->attributes。Doctrine ODM を使用して、問題なく Product インスタンスを mongoDB に永続化します。(rockmongo を使用して) DB にアクセスすると、存在するドキュメントと、attributes配列のクラスに対する JSON ビューの注釈が表示されます。

"_doctrine_class_name": "\Attribute"

しかし、QueryBuilder を使用してその製品を照会すると、Attribute インスタンスの配列を取得する代わりに、PersistentCollection を取得します (実行時にデバッガーでインスタンスを調べます)。

これは遅延読み込みに関係していると思いますが、コードが壊れています。を呼び出そうとするとjson_encode($product)、各インスタンスにカスケードするのではなくAttribtue、空の配列が返されます。

json_encode() から得られると期待するものは次のとおりです。

{
    "property": "some product value",
    "attributes": [
        {
            "property": "some attribute value"
        },
        {
            "property": "some attribute value"
        }
    ]
}

遅延読み込みを無効にするか、各属性インスタンスの適切なインスタンス化を強制する方法はありますか? または、構造全体を手動でトラバースすることなく、目的の JSON オブジェクトを取得できる他の方法はありますか? ありがとう!

4

1 に答える 1

2

遅延読み込みの問題をどのように解決したか:

// parent jsonSerialize method
public function jsonSerialize(){
  $o = new StdClass();
  $o->property = $this->some_property;
  $a = [];
  foreach($this->attributes as $attr){
    $a[] = $attr;
  }
  $o->attributes = $a;
  return $o;
}

これにより、PersistentCollection オブジェクトが適切なインスタンスを 1 つずつ吐き出し、jsonSerializable メソッドが適切にカスケードされて応答します。

醜いIMOですが、問題は解決します。残念ながら、これをすべての埋め込みオブジェクトの依存関係に適用する必要があります。

ホールそれは役立ちます!

于 2013-09-23T01:23:52.820 に答える