2

我们如何将 toJson() 返回对象的键转换为小写或驼峰式?考虑以下示例:

询问:

     $foo = FooQuery::create()
        ->filterByBar($bar)
        ->findOne()
        ->toJson();

结果:

{"Id": 1, "Bar":"StackOverflow"}

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

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

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

我知道这可以通过一些修改来实现,但我想知道是否有更好的方法,最好不要出于性能目的先转换为数组。

4

2 回答 2

0

每次都改变行为

我不认为 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(默认)

返回值

返回其键小写或大写的数组,如果数组不是数组,则返回 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);在下一行输入,因为小写是默认值。

于 2015-11-18T19:39:28.957 回答
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.phpexportTo 方法定义如下:

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因此我们可以使用配置来修改此行为。话虽如此,使用硬编码值而不是可配置值可能是一个很好的理由。

更新: 看起来这只适用于每个生成的模型类的单个实例。对于ObjectCollectionandCollection类,toArrayandexportTo方法使用硬编码的值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但不幸的是,这不起作用。

于 2017-10-01T22:09:18.540 回答