[英]Propel2: lowercase/camelCase keys when converting ObjectCollection toJSON()
我们如何将toJson()返回对象的键转换为小写或camelCase? 考虑以下示例:
查询:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();
结果:
{"Id": 1, "Bar":"StackOverflow"}
默认情况下,它似乎是PascalCase。 如何获取json结果的小写字母属性?
我要引用的函数可以在这里找到,并应用于ObjectCollection。
更新:我想避免使用数组,因为:处理复杂对象时,array_change_key_case()对多维数组不起作用。
我知道这可以通过一些修改来实现,但是我想知道是否有更好的方法,最好不要为了性能目的而先转换为数组。
我认为Propel不会通过传递给该方法的选项为您提供直接简便的方法来执行此操作。 但是,您可以在类中重写*Base
方法。
public function toJSON() {
$fields = array_change_key_case(parent::toJSON());
return $fields;
}
仍使用上面的函数,但有更多详细信息: array_change_key_case
更改数组中所有键的大小写。 您可以在PHP官方文档中阅读有关内容。
array_change_key_case ( array $array [, int $case = CASE_LOWER ] )
返回一个数组,其中所有键均来自小写或大写。 编号索引保持不变。
参数
array要处理的数组
CASE_UPPER或CASE_LOWER的大小写(默认)
返回值
返回数组,其键的大小写为小写或大写;如果array不是数组,则返回FALSE。
适用于(PHP 4> = 4.2.0,PHP 5,PHP 7)
例
<?php
$input_array = array("FirSt" => 1, "SecOnd" => 4);
print_r(array_change_key_case($input_array, CASE_UPPER));
?>
输出
Array
(
[FIRST] => 1
[SECOND] => 4
)
为了你...
在您的示例中,您可以简单地键入$lower_foo = array_change_key_case($foo);
在下一行,因为小写是默认设置。
有一种方法可以配置生成的类以使用camelCase键。 在您的propel.json(或.yaml,.php .ini .xml)配置文件中,添加objectModel,如下所示:
"generator": {
"defaultConnection": "bookstore",
"connections": [ "bookstore" ],
"objectModel": {
"defaultKeyType": "camelName"
}
}
这将使所有键都驼峰成束,但事实证明,这仅适用于toArray()
方法。 当调用toJSON()
,实际上是在使用exportTo('JSON')
方法。 如果查看一下exportTo
方法,可以看到它正在调用:
$this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true)
这迫使exportTo('JSON')
和toJSON()
使用TableMap::TYPE_PHPNAME
作为键类型。 如果查看toArray
方法定义,它将使用"defaultKeyType"
作为默认的$keyType
。 如果不带任何参数调用toArray()
且具有"defaultKeyType": "camelName"
则它将使用TableMap::TYPE_CAMELNAME
并因此将所有键作为camelCase返回。
问题的根源在于Propel的生成器类。 基类在propel/src/Propel/Generator/Builder/Om/ObjectBuilder.php
如果我们看一下它如何生成toArray
方法,我们会发现:
public function toArray(\$keyType = TableMap::$defaultKeyType, \$includeLazyLoadColumns = true, \$alreadyDumpedObjects = array()" . ($hasFks ? ", \$includeForeignObjects = false" : '') . ")
这里的重点是使用TableMap::$defaultKeyType
。 现在,如果我们查看exportTo
方法的生成,我们必须查看templates/baseObjectMethods.php
,exportTo方法的定义如下:
public function exportTo($parser, $includeLazyLoadColumns = true)
{
if (!$parser instanceof AbstractParser) {
$parser = AbstractParser::getParser($parser);
}
return $parser->fromArray($this->toArray(TableMap::TYPE_PHPNAME, $includeLazyLoadColumns, array(), true));
}
这里的重点是它使用硬编码的TableMap::TYPE_PHPNAME
值。 如果将硬编码值更改为TableMap::TYPE_CAMELNAME
并重新生成类,则toJSON()
会将所有键都TableMap::TYPE_CAMELNAME
为camelCase。
因此,不幸的是,如果不修改源代码,就无法使toJSON
使用camelCase。 我认为exportTo
方法应使用defaultKeyType
以便我们可以使用配置来修改此行为。 话虽如此,使用硬编码值而不是可配置值可能是一个很好的理由。
更新:看起来这仅适用于每个生成的模型类的单个实例。 对于ObjectCollection
和Collection
类, toArray
和exportTo
方法使用TableMap::TYPE_PHPNAME
硬编码值
行走/运行/收藏/ Collection.php
public function exportTo($parser, $usePrefix = true, $includeLazyLoadColumns = true)
{
if (!$parser instanceof AbstractParser) {
$parser = AbstractParser::getParser($parser);
}
$array = $this->toArray(null, $usePrefix, TableMap::TYPE_PHPNAME, $includeLazyLoadColumns);
return $parser->listFromArray($array, lcfirst($this->getPluralModelName()));
}
行走/运行/收藏/ ObjectCollection.php
public function toArray($keyColumn = null, $usePrefix = false, $keyType = TableMap::TYPE_CAMELNAME, $includeLazyLoadColumns = true, $alreadyDumpedObjects = [])
{
$ret = [];
$keyGetterMethod = 'get' . $keyColumn;
/** @var $obj ActiveRecordInterface */
foreach ($this->data as $key => $obj) {
$key = null === $keyColumn ? $key : $obj->$keyGetterMethod();
$key = $usePrefix ? ($this->getModel() . '_' . $key) : $key;
$ret[$key] = $obj->toArray($keyType, $includeLazyLoadColumns, $alreadyDumpedObjects, true);
}
return $ret;
}
因此,如果我们可以使用配置文件将它们设置为TableMap::CAMELNAME
,那将是很好的,但是不幸的是这将无法正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.