Propel2:将 ObjectCollection 转换为 JSON() 时的 lowercase/camelCase 个键
Propel2: lowercase/camelCase keys when converting ObjectCollection toJSON()
我们如何将 toJson() 返回对象的键转换为小写或驼峰式?
考虑以下示例:
查询:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();
结果:
{"Id": 1, "Bar":"Whosebug"}
好像默认是PascalCase。
如何获得 json 结果的小写属性?
可以找到我指的函数here and is applied to an ObjectCollection.
更新:
我想避免使用数组,因为:array_change_key_case() 在处理复杂对象时不适用于多维数组。
我知道这可以通过一些修改来实现,但我想知道是否有更好的方法,最好不要先转换为数组以提高性能。
每次都改变行为
我认为 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 ] )
Returns an array with all keys from array lowercased or uppercased.
Numbered indices are left as is.
参数
数组
要处理的数组
案例
CASE_UPPER 或 CASE_LOWER(默认)
Return 值
Returns 一个数组,其键小写或大写,如果数组不是数组,则为 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);
,因为小写字母是默认值。
有一种方法可以将生成的 类 配置为使用驼峰式键。在您的 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
并且因此 return 所有键都是驼峰式。
问题的根源在于 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()
会将所有键作为驼峰式命名。
很遗憾,您不能 toJSON
在不修改源代码的情况下使用驼峰式命名法。我认为 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
,那会很好,但不幸的是,这不起作用。
我们如何将 toJson() 返回对象的键转换为小写或驼峰式? 考虑以下示例:
查询:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();
结果:
{"Id": 1, "Bar":"Whosebug"}
好像默认是PascalCase。 如何获得 json 结果的小写属性?
可以找到我指的函数here and is applied to an ObjectCollection.
更新: 我想避免使用数组,因为:array_change_key_case() 在处理复杂对象时不适用于多维数组。
我知道这可以通过一些修改来实现,但我想知道是否有更好的方法,最好不要先转换为数组以提高性能。
每次都改变行为
我认为 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 ] )
Returns an array with all keys from array lowercased or uppercased. Numbered indices are left as is.
参数
数组 要处理的数组
案例 CASE_UPPER 或 CASE_LOWER(默认)
Return 值
Returns 一个数组,其键小写或大写,如果数组不是数组,则为 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);
,因为小写字母是默认值。
有一种方法可以将生成的 类 配置为使用驼峰式键。在您的 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
并且因此 return 所有键都是驼峰式。
问题的根源在于 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()
会将所有键作为驼峰式命名。
很遗憾,您不能 toJSON
在不修改源代码的情况下使用驼峰式命名法。我认为 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
,那会很好,但不幸的是,这不起作用。