在Propel中使用toArray()时是否可以删除带有*递归*的字段?



我正在使用Propel 2。我正在通过关系为对象补水,如下所示:

$return = OrderQuery::create()
->joinWith('Customer')
->joinWith('Status')
->find()
->toArray(TableMap::TYPE_PHPNAME, true, [], true);

生成的数组将如下所示:

{
"Id": 1,
"CustomerId": 1,
"StatusId": 1,
"Initiated": "2016-01-01T01:01:01+00:00",
"Customer": {
"Id": 1,
"Forname": "Test",
"Surname": "Smith",
"Orders": [
"*RECURSION*"
]
}
"Status": {
"Id": 1,
"Title": "title 1",
"Priority": 1,
"Orders": [
"*RECURSION*"
]
},
}

我想删除值*RECURSION*的字段。我尝试使用$alreadyDumpedObjects(3rd) 参数进行toArray()但这似乎没有帮助。我也可以用unset()调用做某种形式的数组行走,但我希望有更好的方法,也许是格式化程序或其他东西?

对于奖励积分,我非常想删除定义外键关系的列。例如,CustomerId会离开,但Customer会留下来。

为简洁起见,请注意:这个答案有一些非常有用的信息,但有一个解决方案,尽管这个答案说没有。


递归字符串在 propel 中几乎是硬编码的(在 src/Propel/Generator/Builder/Orm/ObjectBuilder.php 中):

if (isset($alreadyDumpedObjects['$objectClassName'][$this->hashCode()])) {
return '*RECURSION*';
}

我想你可以覆盖对象构建器,但我怀疑这就是你要找的。因此,唯一可行的方法是您不想做的事情,循环数组并使用 unset。像这样:

$array = StudyQuery::create()
->leftJoinWithInstitute()
->find()
->toArray();
var_dump($array);
echo PHP_EOL . PHP_EOL . PHP_EOL;
var_dump(cleanupData($array));
/**
* @param array $array
*
* @return array
*/
function cleanupData(array $array)
{
$relationsFound = [];
foreach ($array as $key => $item) {
if ($item === ["*RECURSION*"] || $item == "*RECURSION*") {
unset($array[$key]);
} elseif (is_array($item)) {
$array[$key] = cleanupData($item);
$relationsFound[] = $key;
}
}
foreach ($relationsFound as $relation) {
$key = $relation . 'Id';
if (isset($array[$key])) {
unset($array[$key]);
}
}
return $array;
}

如果存在该关系,这也应该过滤掉 ***Id 字段(前提是关系的 PHPName 与列名匹配)。

当你在 Propel ObjectCollection 上调用toArray方法时,它将调用集合的每个项(查询结果)的toArray。 因此,有两种方法可以实现您要做的事情: 1)覆盖CustomerStatus模型类或CustomerCollectionStatusCollection类中的toArray方法(一个快速而肮脏的解决方案,因为每次使用toArray方法时都会应用它...... 2) 扩展ArrayFormatter类以在format方法中定义"跳过CustomerStatus策略",然后将其添加为格式化程序,仅在需要此特定行为时才使用(在集合上使用setFormatter方法)。

一些参考: http://propelorm.org/documentation/reference/model-criteria.html#using-an-alternative-collection-class

http://propelorm.org/documentation/reference/model-criteria.html#using-an-alternative-formatter

答案似乎很简单。

如果我使用这样的标准ArrayFormatter

$return = OrderQuery::create()
->setFormatter('PropelRuntimeFormatterArrayFormatter');
->joinWith('Customer')
->joinWith('Status')
->find()
->toArray();

返回的是一个ArrayCollection,当调用toArray()时,它与我的原始输出完全相同,只是缺少递归字段。

请注意,当得到一个结果时,例如使用->findPk(1),它将返回一个关联数组,因此您不应显式使用->toArray()

您是否尝试过调用:

unset($return['Customer']['Orders']);
unset($return['Status']['Orders']);

最新更新