Как вернуть дополнительную информацию от избирателя в Symfony4?
У меня есть избиратель, которого я использую, чтобы проверить, может ли текущий пользователь получить доступ к объекту. В доступе может быть отказано по нескольким причинам, и я хотел бы знать, какая именно в Контроллере. Однако избиратель может вернуть только логическое значение, то же самое для isGranted() в контроллере, поэтому я не уверен, по какому каналу я могу передать нужную мне дополнительную информацию. Выброс исключения не годится, так как могут быть другие избиратели, которые еще не были вызваны.
Более близкая вещь, о которой я могу думать, - это флэш-сообщения, которые можно использовать для передачи информации вне аргументов функции и возвращаемых значений, но использовать их в этой ситуации кажется хакерством.
2 ответа
Вы можете зарегистрировать их в службе, как в LoggerInterface, но в свою собственную простую службу сбора данных.
В контейнерных сервисах Symfony по умолчанию используются "синглтоны" - одна и та же служба, полученная из нескольких мест, является одним и тем же объектом (например, регистратором). Создание простого сервиса для сбора информации можно будет изучить позже.
Уже доступны некоторые службы, которые можно использовать для этого, например, получение текущего запроса из стека и добавление нового элемента в один из пакетов параметров.
<?php
class ServiceName
{
private $requestStack;
public function __construct(RequestStack $requestStack) {
$this->requestStack = $requestStack;
$requestStack->getCurrentRequest()->attributes->set('simple-store', 'blah');
//OR, set it in a method that is called deep in the system
}
// And now in a controller
// $value = $request->attributes->get('simple store'),
// Or in Twig template: `{{ dump(app.request.get('simple store')) }}`:
Однако ваша собственная "служба сбора причин", вероятно, будет чище.
Что я сделал, так этоthrow new AccessDeniedHttpException('reason');
непосредственно от избирателя.
Я работаю так же, как symfony илиdenyUnlessGranted()
выдает такое же исключение, если избиратель возвращает false.
Но есть недостатки:
- это заставляет вас использовать
unanimous
стратегия - избиратели не отображаются в профилировщике, на вкладке Безопасность > Решение о доступе.