1

这是我有的两个示例类:

/** @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 实例,然后一些进程在$product->attributes. 我使用 Doctrine ODM 将 Product 实例毫无问题地保存到 mongoDB 中。我可以进入数据库(使用 rockmongo),我看到了 presisted 文档,以及 JSON 视图上对attributes数组类的注释:

"_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"
        }
    ]
}

有什么方法可以禁用延迟加载,或者强制每个 Attribute 实例正确实例化?或者任何其他方式能够获得所需的 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 对象将我们一个一个地吐出适当的实例,然后 jsonSerializable 方法响应良好的级联。

丑陋的IMO,但解决了这个问题。可悲的是,您必须将其应用于您拥有的每个嵌入式对象依赖项。

洞有帮助!

于 2013-09-23T01:23:52.820 回答