Как решить конструктор инъекции 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) вы можете ввести менеджера в экземпляры контейнера. Если есть дополнительные проблемы, я бы хотел их лучше понять.