Managing Objects and Database Connections in PHP Sessions
If you’re not familiar with PHP sessions and how to use session variables, getting up to speed isn’t easy. What makes it difficult to learn is that it’s hard to make sense of the online resources. That includes php.net, which has a ton of little pink and yellow boxes on its pages about sessions, with caveats about important changes between PHP versions. The “right way” to use sessions has changed with successive releases of PHP, and many of the old ways are now either more trouble than they’re worth, or simply may not work at all anymore. Throw in the changes with PHP classes (if you want to store objects in sessions), and the multiple possible ways your server can be configured for handling sessions, and it gets even more confusing. So any tutorial you read that’s more than a couple years old may lead you astray.
I’m not going to try covering all the possible variations, but here’s what works for PHP 4.3.9 with a default session configuration (see the Runtime Configuration section of that page if you want to see the details), using MySQL and Apache. I’m fairly certain this all works in PHP 5 as well, but I haven’t tested it.
- session_start: you need to call session_start() on every page (you can save yourself from repetitive coding by putting this and other page startup code in an include file). Note that by default it stays with the session id that’s automatically set when the user first starts his session – you don’t need to pass in the session id (the php.net documentation could be clearer on that point).
- Requiring your class files: for any objects stored in session variables that you use in a page, you will need to call require_once() on their class files before your call to session_start(). This is necessary for PHP to know how to map the data in the session variable to the class (another good candidate for reuse in an include file).
- session_register: you don’t need to use session_register() anymore. Just use the $_SESSION array to store your variables. I found a lot of online discussions from a few years ago about session_register being essential when putting objects in sessions – that doesn’t apply anymore.
- serialize: if you just want to store your objects in sessions (not in files or database tables), you don’t need to serialize() them yourself, and you don’t have to worry about losing the object type or access to its methods.
- mysql_connect: at first I tried putting a call to mysql_connect() in a startSession method of a database class I created, thinking I’d only need to call it once for the user’s session. That doesn’t work: the connection is lost after the http response for the page is complete. Trying to store the connection in a session variable does not magically persist it for the user. mysql_pconnect() is not the answer either, for reasons outlined in the php.net Persistent Databaase Connection page. The answer is to simply make connections as needed for each page – old connections will be reused if they’re available, so this doesn’t necessarily lead to an unnecessary proliferation of connections. You can even call mysql_connect() repeatedly on a page and it will by default re-use the connection that was initially opened on the page. This is nice if, like me, you’ve written a database class and you have a generic query method in it: you can call mysql_connect() in your query method, and not worry about how many times it’s being called by a particular page.
I should point out all of the foregoing is for garden variety purposes: managing connections for high traffic sites, security, scalability, and dealing with users who don’t accept cookies, are all beyond the scope of this post.
So, in my code I have no calls to session_register() or serialize() (as they’re not needed for storing objects in session variables), and in my database class’s query method, I call mysql_connect(). The main things to remember are requiring your class files before calling session_start(), and doing so on every page.