The architecture of the Session component in Zend Framework 2 is yet undocumented and I'm having some trouble understanding it's practical use (compared to the very intuitive Symfony Session for example).
A short summary of the important pieces:
Zend\Session\Storage\SessionStorage
maps and replaces the$_SESSION
superglobalZend\Session\SessionManager
is a facade to manage the storage, the session cookies, session configuration, session validation, etc.Zend\Session\Container
is a sort of replacement for the oldSession_Namespace
, different Containers share one Manager instance (via a static field).
There is no component that represents a collection of namespaces (containers) and therefore there is no way of using methods like 'issetNamespaceX', 'unsetNamespaceX', etc. Nobody (including the Manager as well as Storage) knows about the containers, whether there are any, and if, how many with what names.
Matthew Weier O'Phinney explained this circumstance as follows:
The Container is a special class for working with isolated segments of the current Storage instance. [...] If anything, a Storage adapter would contain Containers, not the Manager. However, we also want to allow more basic usage of storage, which makes the Container orthogonal to Storage, and which explains the difference in has-a relations.
I see a couple of practical problems with this solution with regard to proper dependency injection. Obviously the Manager can be seen as a service with a rather long lifetime and therefore qualifies for constructor injection. Unfortunately, the Manager has no clue about the Containers which forces me to either inject Containers as well (bad because rather short lived and takes slots away), write my own additional functionality to make the Storage or the Manager Container-aware (should be framework functionality) or create Containers in my Consuming classes (which I want to avoid obviously).
So the Zend solution doesn't seem practical to me. If I want to use the Manager, the FlashMessenger and an additional container, I need to inject 4 (four!) classes. If I do the same with the Symfony Session, I only need to inject 1 (one) class.
Furthermore Containers don't qualify for injection since they're potentially short lived run time objects, which may exist or may not at a given point during script execution. With Symfony Session this is not a problem since the Session is aware of it's bags (containers), with ZF2 this is a problem since the Manager is NOT aware of the Containers.
Main question: How am I supposed to use Zend\Session with Containers in practice?
Additional question: Is there a good reason not to provide real namespace functionality similar to ZF1 or for example similar to the Symfony SessionBag
?
$cnt = new Container('namespaceName'); $cnt['myData'] = 'someValue';
Do you need to do anything further? // Edit: As far as I understand this, a container represents a key of $_SESSION (if using the default storage). – GaillardflashMessenger
? It is actually the perfect example why you only need a container and not a manager at all: the plugin expects some container to put the parameters in, the rest is up to you to configure (though the default config is already pretty OK): zf2.readthedocs.org/en/latest/modules/… – Kc