Zend Expressive - лучший способ внедрить промежуточное ПО
В настоящее время я изучаю Zend Expressive и вижу несколько вариантов доступа к промежуточному программному обеспечению в рамках маршрутов / действий.
В приложении выразительного скелета есть HomePageFactory, куда контейнер внедряется, затем маршрутизатор, шаблонизатор и т. Д. Извлекаются из контейнера, и с их помощью создается новый класс HomePageAction и возвращается.
Например:
class HomePageFactory
{
public function __invoke(ContainerInterface $container)
{
$router = $container->get(RouterInterface::class);
$template = ($container->has(TemplateRendererInterface::class))
? $container->get(TemplateRendererInterface::class)
: null;
return new HomePageAction($router, $template);
}
Затем мне понадобился флеш-мессенджер и наткнулся на следующее:
class SlimFlashMiddlewareFactory
{
public function __invoke($container)
{
return function ($request, $response, $next) {
// Start the session whenever we use this!
session_start();
return $next(
$request->withAttribute('flash', new Messages()),
$response
);
};
}
}
Так что это немного отличается и добавляет промежуточное программное обеспечение к запросу через атрибут. Который затем может быть найден, где это необходимо, например:
$flashMessenger = $request->getAttribute('flash');
Поэтому на самом деле мой вопрос заключается в том, каковы преимущества / недостатки этих двух способов вовлечения FlashMessenger в действие?
Если у меня есть UserService, который занимается извлечением пользователей из базы данных и, следовательно, может понадобиться в нескольких действиях / маршрутах, лучше ли мне изменить HomePageAction & Factory (и любые другие, которые в нем нуждаются) для принятия UserService?
т.е.
class HomePageFactory
{
public function __invoke(ContainerInterface $container)
{
$router = $container->get(RouterInterface::class);
$template = ($container->has(TemplateRendererInterface::class))
? $container->get(TemplateRendererInterface::class)
: null;
$userService = $container->get(App\UserService::class);
return new HomePageAction($router, $template, $userService);
}
Или мне лучше пойти с тем, как работает FlashMessenger (который кажется немного более простым в управлении), и добавить его к запросу через атрибут, чтобы получить доступ к нему таким образом, где это необходимо?
т.е.
$userService = $request->getAttribute('UserService');
Мне интересно, есть ли какие-либо проблемы с производительностью с последним вариантом, хотя я понимаю, что это может быть сделано таким образом только для определенных маршрутов, а не для UserServer, являющегося широким приложением.
У меня есть ощущение (после написания этого вопроса), что на самом деле это Сервис, а не настоящее промежуточное ПО, поэтому мне действительно нужно изменить HomePageAction & Factory и добавить UserService таким образом, а не делать то, что кажется более простым, и использовать атрибут ala FlashMessenger, Но было бы очень удобно, если бы гуру мог помочь прояснить это.
Спасибо заранее.
1 ответ
Я не знаю о различиях в производительности, так как я не проверял это. Но я думаю, что вопрос, который вы должны задать себе, - что делает класс? Требуется ли оно другим промежуточным программным обеспечением до или после вызова класса Action, или оно требуется только в классе Action или где-то еще в приложении.
В вашем случае UserService может позаботиться о регистрации или обновлении пользователя. Эти вещи будут добавлены в ActionFactory, как вам подсказывает ваша интуиция. Однако для аутентификации было бы иначе, если бы это было сделано с промежуточным программным обеспечением. Во-первых, вам нужен этот класс в вашем промежуточном программном обеспечении аутентификации, который вы можете передать в промежуточное программное обеспечение авторизации с запросом (или, возможно, только передать аутентифицированный пользовательский объект, вот что я делаю).
Поэтому я полагаю, что практическое правило заключается в том, что если что-то необходимо для изменения входящего запроса или исходящего ответа до / после действия, вы передаете его вместе с запросом, в противном случае вводите его в действие с фабрикой.
Если вы начнете передавать все с помощью запроса, будет очень трудно отследить. Я считаю, что гораздо проще внедрить как можно больше в само действие, потому что тогда я легко вижу, что нужно внутри этого класса, и я могу проверить его проще.
Такие вещи, как флеш-мессенджер, сеанс и аутентифицированный пользователь, которого я бы вставил в запрос