Symfony 4 продлил запрос на проверку - PullRequest
0 голосов
/ 12 сентября 2018

Я сейчас работаю над проектом API. Я привык к Laravel и теперь мне нужно работать с Symfony. Я хочу использовать запрос, как Laravel, для проверки. Поэтому я расширяю класс Symfony \ Component \ HttpFoundation \ Request. Там я сделал некоторую логику для проверки и очистки входящего запроса.

После этого я добавляю свой недавно созданный запрос в функцию store в контроллере. Но это дает мне ошибку:

Argument 1 passed to App\Controller\Ticket\TicketController::store() must be an instance of App\Validation\Ticket\TicketStoreRequest, instance of Symfony\Component\HttpFoundation\Request given,/vendor/symfony/http-kernel/HttpKernel.php on line 149 {"exception":"[object] (Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Argument 1 passed to App\\Controller\\Ticket\\TicketController::store() must be an instance of App\\Validation\\Ticket\\TicketStoreRequest, instance of Symfony\\Component\\HttpFoundation\\Request given

После некоторого поиска, я нашел несколько вариантов.

  1. Добавить каждое действие контроллера в service.yaml
  2. Создайте прослушиватель и добавьте проверку правильности маршрута

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

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Вот решение, которое развивается на моем другом примере.Это не такой безопасный , как мой другой пример, но он удовлетворяет вашим требованиям.

public function supports(Request $request, ArgumentMetadata $argument)
{    
    $desiredRequestClass = $argument->getType();

    return class_exists($desiredRequestClass);
}

public function resolve(Request $request, ArgumentMetadata $argument)
{
    $desiredRequestClass = $argument->getType();
    $customRequest = new $desiredRequestClass();

    $customRequest->createFromGlobals();
    // TODO: more initialization you might need.

    yield $customRequest;
}

Рекомендуется проверить, является ли $desiredRequestClass потомком Request.

0 голосов
/ 13 сентября 2018

Я нашел несколько подсказок, которые могут указать вам правильное направление:

Symfony поставляется с пятью определителями значений в компоненте HttpKernel:

...

RequestValueResolver

Внедряет текущий запрос, если подсказывает тип с помощью Request или класса, расширяющего Request.

см. https://symfony.com/doc/current/controller/argument_value_resolver.html

Затем страница переходит к описанию реализации пользовательского RequestAttributeValueResolver.Этот пользовательский распознаватель может быть зарегистрирован в вашем services.yml.Хотя в этом примере создается один класс для одного типа атрибута (пользователь), существуют способы создания более динамичной реализации.

В этом примере параметр ArgumentMetadata имеет метод $argument->getType(), который должен содержать строковое представление проверяемого типа:

if (User::class !== $argument->getType()) {
    return false;
}

Ничто не мешает проверитьмассив поддерживаемых типов запросов.Этот массив может управляться как член класса в вашем пользовательском RequestValueResolver.Единственное требование для вашего пользовательского класса RequestValueResolver заключается в том, что метод supports() возвращает true для поддерживаемых типов запросов, а функция resolve() возвращает экземпляр этого поддерживаемого типа запросов.Это должно быть простым, потому что оба метода предоставляют «нужный» класс через параметр ArgumentMetaData.

В качестве альтернативы вы можете реализовать пользовательский RequestValueResolver для каждого пользовательского типа запроса, который вы хотите поддерживать, ноэто не очень элегантно.

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

Для справки: https://api.symfony.com/4.1/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestValueResolver.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...