我们如何将toJson()返回对象的键转换为小写或camelCase? 请考虑以下示例:
查询:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();
结果:
{"Id": 1, "Bar":"StackOverflow"}
默认情况下似乎是PascalCase。 如何在json结果上获得小写属性?
我所指的功能可以找到here and is applied to an ObjectCollection.
更新 我想避免使用数组:在处理复杂对象时,array_change_key_case()不适用于多维数组。
我知道这可以通过一些修改来实现,但我想知道是否有更好的方法,最好不首先为了性能目的而转换为数组。
答案 0 :(得分:0)
我不认为Propel通过您传递给方法的选项为您提供了直接简单的方法。但是,您可以覆盖类中的*Base
方法。
public function toJSON() {
$fields = array_change_key_case(parent::toJSON());
return $fields;
}
仍然使用上面的函数但更详细:array_change_key_case
更改了数组中所有键的大小写。您可以在PHP official docs。
array_change_key_case ( array $array [, int $case = CASE_LOWER ] )
返回一个数组,其中包含来自数组小写或大写的所有键。 编号索引保持不变。
<强>参数强>
阵列 要处理的数组
情况下 CASE_UPPER或CASE_LOWER(默认)
返回值
返回一个数组,其键为lower或uppercased,如果array不是数组,则返回FALSE。
适用于(PHP 4&gt; = 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);
,因为小写是默认值。
答案 1 :(得分:0)
有一种方法可以将生成的类配置为使用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()
会将所有键都设为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
,那将会很好,但不幸的是,它不会起作用。