Using Sessions in Zend Framework 2
As of this writing, there is no official documentation regarding how to use sessions in Zend Framework 2. This article is in no way aiming to be a substitution, but merely a quick introduction on how to get started with sessions in Zend Framework 2.
Let us say, for instance, that you want to keep the username of a user in a session when they log in so that you can access it whenever you need it. This is very simple to accomplish.
namespace MyApplication\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\Session\Container; // We need this when using sessions
class UserController extends AbstractActionController {
public function loginAction() {
// Store username in session
$user_session = new Container('user');
$user_session->username = 'Andy0708';
return $this->redirect()->toRoute('welcome');
}
public function welcomeAction() {
// Retrieve username from session
$user_session = new Container('user');
$username = $user_session->username; // $username now contains 'Andy0708'
}
}
It could barely be any easier, right? Let us take a look at what is actually happening. First we instantiate the Zend\Session\Container class and pass a string (a name). This name is optional; if one is not specified, “Default” will be used as per the class’ constructor. You can think of this name as a namespace; in this way, it is possible to use identical session keys in different containers (or “namespaces”). For example, you may have an “id” key on both “product” and “user”. In this case, you could create two containers – “product” and “user” respectively – and then have “id” keys in both. In this way, the keys do not interfere with each another.
The Zend\Session\Container class extends PHP’s ArrayObject and uses the ArrayObject::ARRAY_AS_PROPS “option”. What this means is that key values can be read and set as properties like in the example above. What actually happens is that the Container class’ offsetGet and offsetSet methods are called. These methods are defined in the ArrayAccess interface, which is implemented by the ArrayObject class. They are then overridden by the Container class. Apologies if that is confusing; in reality, you do not have to know this to make use of sessions; but if you were interested, then that is what happens internally.
Something else interesting happens; the $_SESSION superglobal array is replaced with an instance of Zend\Session\Storage\SessionStorage. Let us take a look at how the $_SESSION variable looks like.
Zend\Session\Storage\SessionStorage Object
(
[isImmutable:protected] =>
[storage:ArrayObject:private] => Array
(
[__ZF] => Array
(
[_REQUEST_ACCESS_TIME] => 1354373227.1111
)
[user] => ArrayObject Object
(
[storage:ArrayObject:private] => Array
(
[username] => Andy0708
)
)
)
)
The SessionStorage class also extends the ArrayObject class (actually, it extends ArrayStorage, which extends ArrayObject), and thus we can use the object as an array. Because of this, the two ways of accessing a session key below are equivalent.
$username = $user_session->username;
$username = $_SESSION['user']['username'];
Hopefully this has helped you learn how to use sessions in Zend Framework 2 and, if you were interested, what happens behind the scenes as well.
Thank you for reading.
Here is what you will learn:
- Understand the theory of Zend Framework in details
- How to implement an enterprise-ready architecture
- Develop professional applications in Zend Framework
- Proficiently work with databases in Zend Framework
- ... and much more!
26 comments on »Using Sessions in Zend Framework 2«
OK, this is great. Thanks!
Question; how do you use the database as an session storage in Zend Framework 2.0 ?
Hello Ibrahim and thank you for your comment.
Storing sessions in a database is not the optimal way to go about it in regards to performance. There may be situations where you would want to centralize the session storage in a database, such as when using using multiple web servers. The efficiency is still better with a cache, but using a database definitely simplifies the production environment. It thus depends on the situation and what you wish to accomplish.
Anyways, I have not actually done this myself, but I took a quick look at the classes within the Zend\Session namespace. Here is what you could try:
1. Create an instance of the Zend\Session\SessionManager class. This class extends the Zend\Session\AbstractMapper class which has a $saveHandler variable.
2. Create an instance of Zend\Session\SaveHandler\DbTableGateway passing an instance of Zend\Db\TableGateway\TableGateway and Zend\Session\SaveHandler\DbTableGatewayOptions to its constructor.
3. On the SessionManager object, set the $saveHandler to the instance created in step 2 via its setSaveHandler() method.
4. Create an instance of Zend\Session\Container and set its $manager variable to the SessionManager instance via its setManager() method.
Again, I have not tried this, so it may not work and you may have to do additional configuration. However, taking a quick look at the files, this should at least get you going in the right direction. Perhaps I will write an article about this when I will have the time to try it out.
I hope it helps.
Thanks,
Andy
Dont use DB as a session controller. its a performance killer.
Better go with APC / Memcache / and alike
thank you
Andy,
Thanks for the efforts documenting it out.
A few questions.
1. How can we make configurations like alive time?
2. Does the above store the information as Cookie? Can we use above and still be in compliance to EU Cookie Laws?
Thanks for the help.
Really Appreciate it.
Hello Rashmirathi,
You are very welcome. I am happy that you found the article useful.
A few months ago, official documentation for Zend\Session was added, and it contains information that answers your first question. Please have a look at the following page; I believe what you are looking for is the remember_me_seconds or cookie_lifetime entries, depending on exactly what you wish to achieve.
As for your second question, I have to say that I have not spent time looking into the cookie law, but a quick search brought me to this page. It describes a session cookie as such:
And later it states the following:
It appears to me that session cookies (which are used for keeping track of session data) are permitted without asking the user for verification, because they are temporary and are limited to a single browsing session, after which they expire. Anything else would be exaggerated in my opinion, because most websites use sessions. Therefore I think that you will be just fine.
I hope this helps.
Best regards,
Bo Andersen AKA Andy
Dear Andy
Thanks for reply.
Sorry for not being able to put my 2nd question properly. I am aware of Europe laws, however, I am eager to know whether Zend stores sessions as permanent cookies.
Here is a little scenario that might help me explain it better,
When we create a normal session (using PHP), it gets deleted after we close browser (or restart system).
However, in my test run (with session code you explained), Zend maintained the values even after I’ve restarted (reboot) the system.
This leads me to believe that Zend maintains it as permanent value, and we might have to provide additional configuration/efforts to make the session expire after one closes the browser.
Now, I have to admit I am new to Zend, and probably would be doing something wrong. I would really appreciate if you can please test it at your end, and may be provide some help.
Warm Regards
Hello Rashmirathi,
I have tried to reproduce your problem, but I have not been able to. With the approach that was outlined in this article, my session data gets removed once I close my browser (tested with Safari and Chrome). It would not make much sense for Zend Framework to persist session data permanently, because sessions are used for storing temporary data. The result would be keeping track of many, many sessions over time.
Perhaps the cause of your problem is related to your development environment. Please try to lookup the following configuration entries in your php.ini file (perhaps call phpinfo() in your code): session.gc_maxlifetime and session.cookie_lifetime. The default values are 1440 and 0, respectively. The former indicates when the session should be considered garbage and be a candidate for garbage collection (even though when the garbage collection actually occurs is non-deterministic). Having the cookie lifetime to 0 means that it will expire once the browser is closed. If the value is set to 100, then the cookie will exist for 100 seconds, even across browser restarts. It is, however, important to note that this does not affect the existence of the session data, but merely the association between your browser instance and the server’s session data. For a more detailed description, please see this page.
Best regards,
Bo Andersen
Thanks for the tutorial. I’m having this problem with a similar code http://stackoverflow.com/questions/17428778/zend-session-container-session-validation-failed-exception-objectclosure
hi,how use session if cookie was off!
I have looking for this for a long time,thank you very much!
Same feeling
Super
Hi,
I have implemented Zend Auth by creating AuthenticationService Object in Module.php in getServiceConfig() Like
& then in controller action, i am getting this object by $this->getServiceLocator()->get(‘AuthService’);
& then authenticating it
& then getting Values using
Its working fine, these values are available.
But the problem is ServiceLocator is not available in Controller constructor so can’t write the above code there & writing this code in each & every action don’t seem to be a good practice.
Could anyone please help out with this?
Thank you, this is the only usable info on ZF 2 sessions on the net. Please try and publish it more prominent for more devs to see. Most of the other information way too technical. Yes we need that, but Frameworks are suppose to save us time, not sending us back to college.
Thank you. I implemented another far more complex solution, and by accident saw this. Needless, your post and method just make so much more sense.
Hello Billy,
Thank you so much for your kind words. I really appreciate it! I am very happy that this post helped you.
Hi.
Thanks for the quick tutorial of using sessions. This is the way I implemented sessions in my app and works fine! But I have a question about the following code:
Why if I do this the $session print is infinite? Is this expected? Although if I do print_r($session->username) it works fine, it’s scary that $session is THAT big.
Thanks again for the tutorial!
Hello Juan,
I am happy that the code is working for you. I am not really sure why print_r prints an infinite array (except that it is related to recursion), although it is something I have experienced many times myself, too. Please try var_dump instead. Anyways, I can recommend you to set up Xdebug on your machine as it really makes debugging so much easier, provided that you are using an IDE such as PhpStorm. And don’t worry, the size of the session is not enormous as print_r might lead one to believe. ;-)
Thanks for reading.
how to destroy the session. i created it like
now how can i destroy it?
Hello Pankaj,
If you want to remove a single value in the session, try this: unset($user_session->username);
If you want to destroy the session altogether, then try this: $user_session->getManager()->getStorage()->clear();
If you want to destroy a specific session namespace (in this example the user namespace), then try this: $user_session->getManager()->getStorage()->clear(‘user’);
I hope that helped.
thanks man this works well for all my modules
Thank you man!
You are welcome – happy to help!
I am getting the session value in same action but not in another action as well as controller?
What can be issue?
Can you solve my problem?
I am storing an array in a session after the login page by using the following code.
where $data is an array. after loggin then i retrieve the same by using the following code.
But i am getting an error when i logged in first time if i referesh the same then its working fine.
Can you suggest me the exactly why i am getting the error on the first time and the solution of this?