Sessions are normally managed by your server and depending upon how involved you get with the PHP setup you need never know how this data is stored. The default setup for PHP is to store session data in temporary files on the server. So why would we want to change how sessions are handled and what advantage can we gain from any changes we make.
Why use database session management?
Sessions allow you maintain persistence within PHP applications. With every HTTP request a PHP application must re-assign every variable and object needed in your application. Sessions allow you to store data that is required to persist past each HTTP request allowing it to be easily retrieved and used.
Sessions are commonly used when creating a secure application, used to store the state of a user e.g. if they are logged in or credentials to control access to content.
By storing session data in a database table you are able to create an application interface that will show information about the users that are logged in. This for example could show the number of users logged into the application or show administrators who is logged in.
If you need to scale your application by adding more than one server, saving your session data in temporary files can lead to major problems. By using database storage you can optimise and unify the session storage, ensuring that session data is always available and consistent.
Obviously there are other solutions for scalable session storage such as APC or MemCache but these solutions are for another post.
How to setup Doctrine database session storage
You first need to add a table to you database schema that will be used to store your session data. Although you can create this table manually, adding it to your scheme also created the model classes that you can later use to interact with the table data.
Session:
columns:
id: { type: string(32), primary: true, notnull: true }
data: { type: string(4000), notnull: true }
time: { type: integer(4), notnull: true }
Once you have added the table to your schema you can build your model and database:
./symfony doctrine:build-all
You then need to configure your symfony application to use this table to store all session data. To do this you need to modify the factories.yml file for your application. Update your file to include the following lines:
all:
storage:
class: sfPDOSessionStorage
param:
db_table: session # Name of the table storing the sessions
db_id_col: id # The primary key column
db_data_col: data # The column where the session data will be stored
db_time_col: time # The column where the timestamp of the session will be stored
database: doctrine # Name of the database connection to use
Once you have modifies your factories.yml file you will need to clear the symfony cache. After that your application should run exactly as it did before except that your users session data will be stored in the database table.
The data column stores all the session data in a serialised form this is deserialized each time a user requests the data. There are many uses for this type of session storage and I hope this brief explanation helps you.
Subscribe to my RSS feed or follow me on twitter to find out about setting up symfony to use APC or MemCache session storage.





15 Comments
It is absolutely imperative if you’re using Doctrine to specify the ID column as well, the schema should look like this:
Session:
columns:
id: { type: string(32), primary: true, notnull: true }
data: { type: string(4000), notnull: true }
time: { type: integer(4), notnull: true }
If you don’t do this your sessions will not work as Doctrine defaults to adding the ID column as an auto incrementing integer, and symfony stores the session id as an md5 hash.
Also, in the example you gave, your integer(11) specification is incorrect, it should be integer(4) with Doctrine, the 11 doesn’t represent length directly, you would use the “length: 11″ parameter for that.
Thanks for you comment Nate! During my testing I did not experience any problems however I will update the post accordingly. Thanks again for taking the time to submit your comments.
No problem, Alistair!
What’s odd is Symfony doesn’t complain about the column with the wrong type, but one of two things happen, a row gets added with the auto-incremented id, and no data is stored, causing the session to not be persistent.
Or, somehow the md5 sum is able to be translated into a crazy integer, and the session will operate correctly.
I spend quite a few hours trying to figure out what was going on. =P
A very nice, easy to follow tutorial. Now I have my sessions for my latest symfony project nicely stored in the database
Many Thanks.
Chris.
Thanks for the post. The symfony docs aren’t clear about the data type sessions table fields. Thanks again.
Your welcome. Most examples provide the SQL to create the table outside of your symfony project. I wanted to show an example using the schema syntax and building the model directly.
Excellent, thanks for this very straightforward explanation, plus comments from other commenters.
Hello,
What I’m wondering about (and sorry of this is a newbie question) is that, symfony stores the session data in a serialized form. Can this be changed? More importantly, should this be changed? I usually see session data stored in columns seperately. Does this mean, that each time session data is requested, you have to de-serialize it? Does that effect performance?
Thanks
Hi,
Symfony uses the standard PHP session handler. Due to how a session must be stored and retrieved between each HTTP request the data is stored in a serialized form. Unless you are storing large object structures in session this should not cause you any problems. I’m unsure of your requirements to store data in columns?
I would suggest that you should possibly look at adding additional protected variables to the myUser class and then create getter and setter methods that will retrieve the data from session. You can then access the data through a common interface.
Hi,
You said that by storing sessions in a database you are able to retrieve logged in users. Could you please give an example of how to do this?
Hi,
You can simple make a select on the session tabe and count the results. If everything is setup correctly the data rows are deleted after a user leaves the site.
Yes, I know that. But I refer to specific users, not at the number of logged in users.
to define id column can be use param fixed:true then id field will be fixed size char(32) not varchar(32) and performance should be better.
id: { type: string(32), primary: true, notnull: true, fixed:true }
Thanks for this great tutorial!
Hi,
Great post! I just used it because the prod servers we had to use were load-balanced and we were not able to install memcache.
The only concern I have: how to clear timed-out sessions? We created a (really simple) symfony task for that, because we weren’t sure if there is some “symfony magic” that automatically clears sessions. I haven’t find any. If you don’t clear expired sessions, I think the DB table will grow infinitely, right?
Depending upon you ini config the sessions should be removed automatically.
One Trackback
[...] Alistair Stead pour son article « symfony Doctrine database session storage« [...]