如何将toJson()返回对象的键转换为小写或camelCase?请考虑以下示例:
查询:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();结果:
{"Id": 1, "Bar":"StackOverflow"}默认情况下,它似乎是PascalCase。如何获得json结果的小写属性?
我所指的函数可以找到这里,并应用于ObjectCollection。
更新:我希望避免使用数组,因为: array_change_key_case()在处理复杂对象时不适用于多维数组。
我知道可以通过一些修改来实现这一点,但我想知道是否有更好的方法,最好不要先对数组进行转换以提高性能。
发布于 2017-10-01 22:09:18
有一种方法可以将生成的类配置为使用camelCase键。在propel.json (或.yaml,.php .ini .xml)配置文件中添加objectModel,如下所示:
"generator": {
"defaultConnection": "bookstore",
"connections": [ "bookstore" ],
"objectModel": {
"defaultKeyType": "camelName"
}
}这将使您的所有键都成为camelCased,但事实证明,这只适用于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()将将所有键作为camelCase。
因此,不幸的是,如果不修改源代码,toJSON就不能使用camelCase。我认为exportTo方法应该使用defaultKeyType,这样我们就可以使用配置来修改这种行为。尽管如此,也许有一个非常好的理由拥有硬编码值而不是可配置值。
更新:看起来只适用于每个生成的模型类的一个实例。对于ObjectCollection和Collection类,toArray和exportTo方法使用TableMap::TYPE_PHPNAME的硬编码值。
Propel/Runtime/Collection/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()));
}Propel/Runtime/Collection/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,这将是一件好事,但不幸的是,这是行不通的。
发布于 2015-11-18 19:39:28
每次改变行为
我不认为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 ] )返回一个数组,其中包含数组中的所有键,这些键来自低精度或超感知的数组。编号的索引保持原样。
参数
数组来处理该数组。
CASE_UPPER或CASE_LOWER (默认)
返回值
返回具有较低或超感知键的数组,如果数组不是数组,则返回FALSE。
工作于(PHP4 >= 4.2.0,PHP5,PHP7)
示例
<?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);,因为小写是默认的。
https://stackoverflow.com/questions/33788345
复制相似问题