Как мы можем преобразовать ключи возвращаемого объекта toJson () в нижний регистр или camelCase?
Рассмотрим следующий пример:
Запрос:
$foo = FooQuery::create()
->filterByBar($bar)
->findOne()
->toJson();
Результат:
{"Id": 1, "Bar":"StackOverflow"}
Похоже, это PascalCase по умолчанию.
Как я могу получить свойства нижнего регистра для результата json?
Функция, на которую я ссылаюсь, может быть найдена здесь и применяется к ObjectCollection.
Обновить:
Я хочу избежать использования массивов, так как: array_change_key_case () не работает для многомерных массивов при работе со сложными объектами.
Я знаю, что это может быть достигнуто с помощью некоторых модификаций, но я хочу знать, есть ли лучший подход, желательно без приведения к массиву в первую очередь для повышения производительности.
Я не думаю, что 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, если массив не является массивом.
Работает в (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);
на следующей строке, поскольку строчные буквы по умолчанию.
Существует способ настроить сгенерированные классы на использование ключей camelCase. В вашем файле конфигурации propel.json (или .yaml, .php .ini .xml) добавьте объектную модель следующим образом:
"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
Propel / выполнения / Коллекция / 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 / выполнения / Коллекция / 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
но, к сожалению, это не сработает.