Как решить конструктор инъекции Zend\Session?
Архитектура компонента Session в Zend Framework 2 еще не документирована, и у меня есть некоторые проблемы с пониманием ее практического использования (по сравнению с очень интуитивным сеансом Symfony, например).
Краткий обзор важных частей:
-
Zend\Session\Storage\SessionStorage
отображает и заменяет суперклассов $_SESSION
-
Zend\Session\SessionManager
- это фасад для управления хранилищем, файлы cookie сеанса, конфигурация сеанса, проверка сеанса и т.д.
-
Zend\Session\Container
является своего рода заменой для старого Session_Namespace
, разные контейнеры совместно используют один экземпляр менеджера (через статическое поле).
Нет компонента, который представляет собой коллекцию пространств имен (контейнеров), и поэтому нет способа использовать такие методы, как "issetNamespaceX", "unsetNamespaceX" и т.д. Никто (включая Менеджера, а также Хранение) не знает об контейнерах, есть ли какие-либо, и если, сколько с каким именем.
Мэтью Вейер О'Финни объяснил это обстоятельство следующим образом:
Контейнер является специальным классом для работы с изолированными сегментами текущий экземпляр хранилища. [...] Во всяком случае, адаптер хранения будет содержать Контейнеры, а не Менеджер. Однако мы также хотим позволяют более простое использование хранилища, что делает Контейнер ортогонально к Storage, и это объясняет разницу в has-a отношения.
Я вижу пару практических проблем с этим решением в отношении правильной инъекции зависимостей. Очевидно, что Менеджера можно рассматривать как услугу с довольно продолжительным сроком службы и поэтому имеет право на конструкторскую инъекцию. К сожалению, менеджер не имеет понятия о контейнерах, которые заставляют меня либо вводить Контейнеры (плохой, потому что они довольно короткие и отнимают прорези), напишите мои собственные дополнительные функции, чтобы сделать хранилище или диспетчер контейнера осведомленным (должен быть фреймворк) функциональность) или создать Контейнеры в моих классах потребления (чего я хочу явно избегать).
Итак, решение Zend мне кажется нецелесообразным. Если я хочу использовать Менеджер, FlashMessenger и дополнительный контейнер, мне нужно ввести 4 (четыре!) Класса. Если я сделаю то же самое с сеансом Symfony, мне нужно всего лишь ввести 1 (один) класс.
Кроме того, контейнеры не могут претендовать на инъекцию, поскольку они потенциально непродолжительные объекты времени выполнения, которые могут существовать или не быть в заданной точке во время выполнения script. С помощью сеанса Symfony это не проблема, так как Session знает о мешках (контейнерах), с ZF2 это проблема, поскольку менеджер НЕ знает контейнеры.
Основной вопрос: Как я должен использовать Zend\Session с контейнерами на практике?
Дополнительный вопрос: есть ли веская причина не предоставлять реальную функциональность пространства имен, аналогичную ZF1 или, например, аналогичную Symfony SessionBag
?
Ответы
Ответ 1
Я не уверен на 100%. Я понимаю, на какие проблемы вы сталкиваетесь.
Сначала конструктор для Container
принимает как пространство имен для контейнера, так и необязательно экземпляр Manager
: $container = new Container('your container namespace here', $manager)
. Вы также можете указать экземпляр менеджера по умолчанию: Container::setDefaultManager($manager)
.
Во-вторых, Container
представляет собой просто именованный массив в экземпляре Storage
. Таким образом, вы можете проверить наличие контейнера, выполнив вызов isset($storage['your container namespace here'])
.
Какие конкретные проблемы вы сталкиваетесь с тем, что вышеизложенное не решает? Из вашего описания это звучит так: (а) вы не знали, что контейнеры имеют отношение 1:1 к хранилищу, и (b) вы можете ввести менеджера в экземпляры контейнера. Если есть дополнительные проблемы, я бы хотел их лучше понять.