В настоящее время я изучаю 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 & Фабрика (и любые другие, которые нуждаются в этом), чтобы принять 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 & Фабрика и добавление UserService таким образом, вместо того, чтобы делать то, что кажется проще, и с использованием атрибута аля FlashMessenger. Но было бы очень удобно, если бы гуру мог помочь прояснить это.
Спасибо заранее.
Я не знаю о различиях в производительности, так как я не проверял это. Но я думаю, что вопрос, который вам нужно задать себе, — что делает класс? Требуется ли оно другим промежуточным программным обеспечением до или после вызова класса Action, или оно требуется только в классе Action или где-то еще в приложении.
В вашем случае UserService может позаботиться о регистрации или обновлении пользователя. Эти вещи будут добавлены в ActionFactory, как вам подсказывает ваша интуиция. Однако для аутентификации было бы иначе, если бы это было сделано с промежуточным программным обеспечением. Во-первых, вам нужен этот класс в вашем промежуточном программном обеспечении для аутентификации, который вы можете передать своему промежуточному программному обеспечению для авторизации по запросу (или, возможно, только передать аутентифицированный пользовательский объект, это то, что я делаю).
Поэтому я полагаю, что практическое правило заключается в том, что если что-то необходимо для изменения входящего запроса или исходящего ответа до / после действия, вы передаете его вместе с запросом, в противном случае добавляете его в действие с фабрикой.
Если вы начнете передавать все с помощью запроса, будет очень трудно отследить. Я считаю, что гораздо проще внедрить как можно больше в само действие, потому что тогда я легко вижу, что нужно внутри этого класса, и я могу проверить его проще.
Такие вещи, как флеш-мессенджер, сеанс и аутентифицированный пользователь, которого я бы вставил в запрос.
Других решений пока нет …