Как передать пользовательские данные в сервис с контроллера с помощью PHP-DI
Мои контроллеры имеют объект учетной записи и объект пользователя, и почти все взаимодействия с бэкэндом зависят от этих объектов, чтобы установить права доступа, ограничить загрузку данных, ++++ (я не использую какую-либо конкретную среду)
У моих контроллеров есть разные способы узнать, какие объекты использовать, но обычно это происходит в сеансе для зарегистрированных пользователей (но бэкэнд-процессы могут получать эту информацию из очереди и т. Д.).
Итак, я пытаюсь настроить PHP-DI для моего ServiceLayer, и мне нужно внедрить учетную запись, объект User в службы, но как мне сделать это хорошим способом, гарантируя, что они имеют правильные значения?
Моей первой попыткой было передать это в ContainerFactory:
public static function getInstance(EnvironmentConfig $config, ?int $accountId, ?int $userId):Container
Затем используйте эти значения динамически в конфигурации, однако это перестало работать, когда я включил компиляцию, поскольку значения кэшировались. (очевидно, но да..)
Я могу использовать фабрику для создания объекта userObject и Account и, например, считывать значения непосредственно из сеанса на фабрике. Но это выглядит очень грязно, и будет работать только в определенных контекстах.
Документация касается только специфических для среды значений, поэтому я не нашел хорошего описания того, как обращаться с данными, специфичными для сессии.
Любые предлагаемые шаблоны для этого?
2 ответа
Контейнер должен хранить объекты без сохранения состояния. Специфичные для запроса данные, такие как сессия, зарегистрированный пользователь и т. Д., Не являются зависимостями, попытка поместить их в контейнер означает возврат к глобальному состоянию.
Я настоятельно рекомендую вам передавать эти данные другими способами: параметрами вызова метода, хранить их внутри объекта Request, а в худшем случае вводить RequestStack
или похожий объект. Это то, что сделал Symfony, когда они отказались от инъекций Request
объекты напрямую с помощью контейнера: https://symfony.com/blog/new-in-symfony-2-4-the-request-stack
Спасибо за ваш быстрый ответ. В принципе, я согласен, эти вещи являются пограничными, поскольку они являются неотъемлемой частью всего уровня приложения, приложение имеет глобальное состояние, зависящее от зарегистрированной учетной записи и пользователя, и это остается таким же для всего сеанса. Да, это технически специфический запрос, но мне нужно, чтобы уровень сервиса знал об этом, так как от этого зависит большая бизнес-логика.
параметры вызова метода были бы технически чистыми, но беспорядочными и подверженными ошибкам, поскольку это были бы одни и те же параметры, повторяющиеся во всем приложении. Все сервисные вызовы будут выглядеть так:
$service->getCategory($id, $user, $account);
$service->getCategoryByMain($mainCategoryId, $user, $account);
Поэтому я смотрел на PHP-DI, чтобы получить более чистую инъекцию, чем моя текущая установка, где я получаю длинные конструкторы Service, которые одинаковы во всем приложении.
Не уверен, как сделать это аккуратно, так что откройте для любых полезных практических советов:) Может быть, PHP-DI здесь не тот инструмент, но это проблема DI, где у меня есть набор зависимостей, которые нужно опустить в стек.