Я работаю над переносом существующего Symfony 2.8
, которое я не создал. Предыдущие разработчики не доступны для вопросов.
Большую часть кода легко понять, но в какой-то момент я просто не могу понять, почему это работает:
Параметр контроллера / действия автоматически десериализуется из данных JSON
в пользовательский объект. В этом нет ничего особенного, я не понимаю, как / где Symfony сказали, что делать. С моей точки зрения, важные данные конфигурации отсутствуют, но они все равно работают.
Это было бы хорошо, но не понимая, почему это работает в этом случае, я не могу понять, почему он больше не работает при переносе проекта в Symfony 3.4
...
Извините за (очень) длинный вопрос, но я пробовал разные способы решить проблему и ответить на вопросы, но все они привели к различным проблемам ...
Использование следующих комплектов
sensio/framework-extra-bundle v3.0.29
friendsofsymfony/rest-bundle 2.4.0
jms/serializer 1.13.0
jms/serializer-bundle 1.5.0
Config:
// app/config/config.yml
sensio_framework_extra:
request: { converters: true }
fos_rest:
...
body_converter:
enabled: true
#jms_serializer: (not configured)
# ...
Код:
// src/AppBundle/Util/SortInfo.php
class SortInfo {
public $sortOrder;
public $sortBy;
}
// src/AppBundle/Resources/serializer/Util.SortInfo.yml
AppBundle\Util\SortInfo:
exclusion_policy: ALL
properties:
sortOrder:
type: string
expose: true
sortBy:
type: string
expose: true
// src/AppBundle/Controller/SortingController.php
class SortingController extends Controller {
...
/**
* @FOSRest\View()
*/
public function sortAction(SortInfo $sortInfo) {
$this->logger->info("sortAction");
$this->logger->info(" ".gettype($sortInfo)." -- ".get_class($sortInfo));
$this->logger->info(" ".$sortInfo->sortOrder." -- ".$sortInfo->sortBy);
...
}
}
Вот и все. После копания в течение нескольких часов я не смог найти какой-либо явной конфигурации, которая сообщала бы методу sortAction
для автоматического преобразования данных JSON
из запроса. Но это работает.
Запрос со следующим содержанием JSON
приводит к следующему выводу журнала:
// JSON content
{"sortOrder":"ASC", "sortBy":"name"}
// Log output
sortAction
object -- AppBundle\Util\SortInfo
ASC -- name
Почему это работает?
Как уже было сказано, это нормально, но проблема в том, что тот же код не работает с Symfony 3.4
и более новыми версиями FOSRest, ExtrasBundle и JMSSerializer:
sensio/framework-extra-bundle v5.2.4
friendsofsymfony/rest-bundle 2.5.0
jms/serializer 2.1.0
jms/serializer-bundle 3.0.0
Запрос с теми же данными JSON
приводит к следующему выводу журнала в `Symfony 3.4 ':
// Log output
sortAction
object -- AppBundle\Util\SortInfo
--
Таким образом, хотя SortInfo
создан (не ноль), свойства sortBy
и sortOrder
являются пустыми / нулевыми.
Как это может быть? Я не понимаю, почему данные десериализованы в первую очередь, но как можно создать объект SortInfo
без установки свойств, еще более загадочно.
В Symfony 2.8
для процесса необходим файл Util.SortInfo.yml
. Удаление этих файлов приводит к исключению:
Symfony \ Component \ HttpKernel \ Exception \ BadRequestHttpException: "Вы
должен определить тип для
AppBundle \ Util \ SortInfo :: $ SortBy. "
at /.../vendor/friendsofsymfony/rest-bundle/Request/RequestBodyParamConverter.php
Здесь я не понимаю, почему SortInfo::$sortBy
проблема, а не SortInfo
сама по себе. Кроме того, удаление файла в Symfony 3.4
ничего не меняет.
Но по крайней мере это сообщение об ошибке подтверждает, что FOS RequestBodyParamConverter
участвует в процессе.
В соответствии с Symfony docs необходимо вручную указать параметр, который должен быть преобразован (хотя он прекрасно работает без этой конфигурации в Symfony 2.8
):
/**
* @FOSRest\View()
* @ParamConverter("sortInfo", converter="fos_rest.request_body")
*/
public function sortAction(SortInfo $sortInfo) {
...
}
Однако добавление этой конфигурации приводит к другой ошибке в Symfony 3.4
:
Uncaught PHP Exception RuntimeException: «Конвертер
'fos_rest.request_body' не поддерживает преобразование параметра
'$ SortInfo'
Итог:
- Это все очень загадочно.
- Почему он работает без проблем в
Symfony 2.8
, хотя в отношении документации отсутствует необходимая конфигурация (явно укажите ParamConverter)
- Почему это не работает в Symfony 3.4?