Propel2: строчные / camelCase ключи при преобразовании ObjectCollection в JSON ()

Как мы можем преобразовать ключи возвращаемого объекта toJson () в нижний регистр или camelCase?
Рассмотрим следующий пример:

Запрос:

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

Результат:

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

Похоже, это PascalCase по умолчанию.
Как я могу получить свойства нижнего регистра для результата json?

Функция, на которую я ссылаюсь, может быть найдена здесь и применяется к ObjectCollection.

Обновить:
Я хочу избежать использования массивов, так как: array_change_key_case () не работает для многомерных массивов при работе со сложными объектами.

Я знаю, что это может быть достигнуто с помощью некоторых модификаций, но я хочу знать, есть ли лучший подход, желательно без приведения к массиву в первую очередь для повышения производительности.

2

Решение

Для изменения поведения каждый раз

Я не думаю, что 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); на следующей строке, поскольку строчные буквы по умолчанию.

0

Другие решения

Существует способ настроить сгенерированные классы на использование ключей 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 но, к сожалению, это не сработает.

0

По вопросам рекламы [email protected]