问题描述
|
iv收到我的文档的完整数组(包含嵌入式childs集合和对象的所有数据)时遇到问题。我的文档看起来像这样:
use Doctrine\\Common\\Collections\\ArrayCollection;
/** @Document(collection=\"user\") */
class User {
/** @Id */
protected $id;
/** @String */
protected $firstname;
/** @String */
protected $lastname;
/** @EmbedMany(targetDocument=\"Email\") */
protected $email;
/** @EmbedMany(targetDocument=\"Address\") */
protected $address;
/** @EmbedMany(targetDocument=\"Subscription\") */
protected $subscription;
/**
* Construct the user
*
* @param array $properties
* @throws User_Exception
*/
public function __construct(array $properties = array()) {
$this->email = new ArrayCollection();
$this->address = new ArrayCollection();
$this->subscription = new ArrayCollection();
foreach($properties as $name => $value){
$this->{$name} = $value;
}
}
...
我需要一个完整的嵌入式集合数组,以输出整个数据并通过json呈现。我的查询如下所示:
$query = $this->_dbContainer->getDocumentManager()->createqueryBuilder(\'User\')->field(\'deletedAt\')->exists(false);
$result = $query->field(\'id\')->equals($id)->getQuery()->getSingleResult();
例如,如果我这样调用toArray()
函数:
$array = $result->getSubscription()->toArray();
print_r($array);
然后输出ist只是顶层的一个数组:
[0] => Object Subscription...
[1] => Object Subscription...
...
我如何轻松获得这样的数组?
[0] => array(\'subscriptionLabel\' => \'value1\',\'field\' => \'value1\',...)
[1] => array(\'subscriptionLabel\' => \'value2\',\'field\' => \'value2\',...)
...
是否有任何最佳做法或可能缺少一些帮助程序脚本来防止类似此代码的丑陋行为(如何处理child-> child-> child szenarios?ugly-> ugly ugly-> ugly ugly ugly-> ...):
$example = array();
foreach($result->getSubscription() as $key => $subscription) {
$example[$key][\'subscriptionLabel\'] = $subscription->getSubscriptionLabel();
$example[$key][\'field\'] = $subscription->getField();
...
}
非常感谢,
史蒂芬
解决方法
该死的简单答案!只需使用-> hydrate(false)就可以了。
查找查询的结果
默认是水合的,你得到
文档对象返回而不是
数组。您可以禁用它并获取
原始结果直接从
使用水合物的蒙哥(假)
方法:
<?php
$users = $dm->createQueryBuilder(\'User\')
->hydrate(false)
->getQuery()
->execute();
print_r($users);
, 我最近遇到了同样的需求,并通过使用toArray()函数和JsonSerializable为我的所有实体创建了一个基类来解决了这一需求。它也转换所有嵌套的引用。
/**
* @ODM\\MappedSuperclass
*/
abstract class BaseDocument implements \\JsonSerializable
{
public function jsonSerialize() {
return $this->toArray();
}
public function toArray() {
$getter_names = get_class_methods(get_class($this));
$gettable_attributes = array();
foreach ($getter_names as $key => $funcName) {
if(substr($funcName,3) === \'get\') {
$propName = strtolower(substr($funcName,3,1));
$propName .= substr($funcName,4);
$value = $this->$funcName();
if (is_object($value) && get_class($value) == \'Doctrine\\ODM\\MongoDB\\PersistentCollection\') {
$values = array();
$collection = $value;
foreach ($collection as $obj) {
$values[] = $obj->toArray();
}
$gettable_attributes[$propName] = $values;
}
else {
$gettable_attributes[$propName] = $value;
}
}
}
return $gettable_attributes;
}
}
现在,我可以使用json_encode($ doc)将实体序列化为数组或json字符串。 am
, 作为Rooster242的坦克,您甚至可以使用php is_subclass_of函数将toArray递归地应用于嵌入式文档,这些文档本身扩展了BaseDocument:
/**
* @ODM\\MappedSuperclass
*/
abstract class BaseDocument implements \\JsonSerializable
{
public function jsonSerialize() {
return $this->toArray();
}
public function toArray() {
$getter_names = get_class_methods(get_class($this));
$gettable_attributes = array();
foreach ($getter_names as $key => $funcName) {
if(substr($funcName,4);
$value = $this->$funcName();
if (is_object($value) && is_subclass_of($value,\"BaseDocument\")) {
$gettable_attributes[$propName] = $value->toArray();
} elseif (is_object($value) && get_class($value) == \'Doctrine\\ODM\\MongoDB\\PersistentCollection\') {
$values = array();
$collection = $value;
foreach ($collection as $obj) {
if (is_subclass_of($obj,\"BaseDocument\")) {
$values[] = $obj->toArray();
} else {
$values[] = $obj;
}
}
$gettable_attributes[$propName] = $values;
}
else {
$gettable_attributes[$propName] = $value;
}
}
}
return $gettable_attributes;
}
}
, 只是使它更加通用,可以完美地工作。只是别忘了用您的文档和嵌入扩展它。
<?php
namespace App\\Documents;
use Doctrine\\ODM\\MongoDB\\Mapping\\Annotations as ODM;
use Doctrine\\ODM\\MongoDB\\PersistentCollection;
/**
* @ODM\\MappedSuperclass
*/
abstract class BaseDocument implements \\JsonSerializable
{
/**
* @return array
*/
public function jsonSerialize()
{
return $this->toArray();
}
/**
* @return array
*/
public function toArray()
{
$getterNames = get_class_methods(get_class($this));
$gettableAttributes = [];
foreach ($getterNames as $funcName) {
if (substr($funcName,3) !== \'get\') {
continue;
}
$propName = strtolower(substr($funcName,1));
$propName .= substr($funcName,4);
$value = $this->$funcName();
$gettableAttributes[$propName] = $value;
if (is_object($value)) {
if ($value instanceof PersistentCollection) {
$values = [];
$collection = $value;
foreach ($collection as $obj) {
/** @var BaseDocument $obj */
if ($obj instanceof \\JsonSerializable) {
$values[] = $obj->toArray();
} else {
$values[] = $obj;
}
}
$gettableAttributes[$propName] = $values;
} elseif ($value instanceof \\JsonSerializable) {
/** @var BaseDocument $value */
$gettableAttributes[$propName] = $value->toArray();
}
}
}
return $gettableAttributes;
}
}