Архитектура компонента 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
?