首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Propel2:转换ObjectCollection toJSON()时的小写/camelCase键

Propel2:转换ObjectCollection toJSON()时的小写/camelCase键
EN

Stack Overflow用户
提问于 2015-11-18 19:10:07
回答 2查看 1.6K关注 0票数 2

如何将toJson()返回对象的键转换为小写或camelCase?请考虑以下示例:

查询:

代码语言:javascript
复制
     $foo = FooQuery::create()
        ->filterByBar($bar)
        ->findOne()
        ->toJson();

结果:

代码语言:javascript
复制
{"Id": 1, "Bar":"StackOverflow"}

默认情况下,它似乎是PascalCase。如何获得json结果的小写属性?

我所指的函数可以找到这里,并应用于ObjectCollection。

更新:我希望避免使用数组,因为: array_change_key_case()在处理复杂对象时不适用于多维数组。

我知道可以通过一些修改来实现这一点,但我想知道是否有更好的方法,最好不要先对数组进行转换以提高性能。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-01 22:09:18

有一种方法可以将生成的类配置为使用camelCase键。在propel.json (或.yaml,.php .ini .xml)配置文件中添加objectModel,如下所示:

代码语言:javascript
复制
"generator": {
  "defaultConnection": "bookstore",
  "connections": [ "bookstore" ],
  "objectModel": {
    "defaultKeyType": "camelName"
  }
}

这将使您的所有键都成为camelCased,但事实证明,这只适用于toArray()方法。当您调用toJSON()时,实际上使用的是exportTo('JSON')方法。如果您查看exportTo方法,可以看到它正在调用:

代码语言:javascript
复制
$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中生成的:

代码语言:javascript
复制
public function toArray(\$keyType = TableMap::$defaultKeyType, \$includeLazyLoadColumns = true, \$alreadyDumpedObjects = array()" . ($hasFks ? ", \$includeForeignObjects = false" : '') . ")

这里最重要的一点是它正在使用TableMap::$defaultKeyType。现在,如果我们查看exportTo方法生成,我们必须在templates/baseObjectMethods.php中查看,exportTo方法定义如下:

代码语言:javascript
复制
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,这样我们就可以使用配置来修改这种行为。尽管如此,也许有一个非常好的理由拥有硬编码值而不是可配置值。

更新:看起来只适用于每个生成的模型类的一个实例。对于ObjectCollectionCollection类,toArrayexportTo方法使用TableMap::TYPE_PHPNAME的硬编码值。

Propel/Runtime/Collection/Collection.php

代码语言:javascript
复制
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

代码语言:javascript
复制
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,这将是一件好事,但不幸的是,这是行不通的。

票数 0
EN

Stack Overflow用户

发布于 2015-11-18 19:39:28

每次改变行为

我不认为Propel通过传递给该方法的选项给您提供了一种直接、简单的方法来实现这一点。但是,您可以重写类中的*Base方法。

代码语言:javascript
复制
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)

示例

代码语言:javascript
复制
<?php
$input_array = array("FirSt" => 1, "SecOnd" => 4);
print_r(array_change_key_case($input_array, CASE_UPPER));
?>

输出

代码语言:javascript
复制
Array
(
    [FIRST] => 1
    [SECOND] => 4
)

给你.

在您的示例中,您只需在下一行输入$lower_foo = array_change_key_case($foo);,因为小写是默认的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33788345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档