Sessions are automatically managed by PHP as long as you call session_start() at the top of every script which needs access to the session. However, many people don't know what actually happens when you call session_start().
When your script requests access to the session, PHP checks to see if the user passed in a cookie called PHPSESSID. If so, the value in the cookie (a 32-character unique hex string) is used as the filename to look up the user's actual session DATA from a temporary file on the server. That data is a plaintext string serialized into a format that PHP can turn back into the session array that you're familiar with already.
Of course, if there is not a PHPSESSID cookie in the user's cookie headers, one is created for that user and the cookie is set on their machine with an expiration time of zero (which means it persists until the window is closed). The data you put into $_SESSION is serialized and placed into the temporary session file when the script dies normally. Sessions will only fail to be written if the script comes to some catastrophic end, such as a segmentation fault.
NOTE: The serialization format PHP uses for session data is NOT the serialization format you get from the built-in serialize() function. The data that will be passed into your write() function will not be able to be parsed by any built-in function. If you need to store your data in some other format (if you need it to be readable by another programming language, for instance) then you will have to use the existing $_SESSION array directly. This is more memory and processor intensive so it should be avoided if possible.
Now the default PHP session management functions work just fine for most uses, and there is no reason to create a custom session handler if all you have is one server with a moderate amount of traffic and session use. However, remember that session data is stored locally on your server's hard drive. If you have more than one web server, obviously you will need to figure out another way to manage sessions so that the user's session can be restored regardless of which web server they hit. This is where PHP's session_set_save_handler() comes in handy.
Custom Session Handling - The Basics
Using session_set_save_handler(), you can set a custom function for every session operation (open, close, read, write, destroy, and garbage collection).
OPEN The "open" function works like the session's constructor. The open function will establish a connection to whatever storage location you choose to use for the session. For our purposes, we will be using a MySQL database, so the "open" function will he used to initialize the database connection.
The open function needs to accept two arguments. The first argument is the location to save the session file (a folder location) and the second is the name of the session file (the value of the PHPSESSID cookie). Even though your functions may not need those values, it still must accept them to avoid throwing errors.
CLOSE The "close" functions works like the session's destructor. The close function will disconnect from the storage location and perform any cleanup operations other than garbage collection (which has its own function). For our purposes (and for most purposes) there is no need for a close function or a destructor. Any open database, memcache, or filesystem connections are closed when the script dies anyway.
READ The "read" function loads the session data from its storage location and returns a serialized string representing the serialized session data. Remember, the serialization function used by PHP for sessions is NOT serialize().
The read() function accepts a single argument, the session ID (the contents of the PHPSESSID cookie. A serialized string must be returned, which PHP will unserialize and place into $_SESSION. Even if you want to store your session data in another format, you must return a “php session serialized” string. More on this advanced technique later.
WRITE The "write" function is what actually stores the session data into the storage location. The write function accepts two arguments: the session ID and the session data (which is already a serialized string at this point). The session data being stored has to be accessible by the read() function, obviously.
DESTROY The session "destroy" function is what gets invoked if session_destroy() is called by your scripts. Destroying the session involves simply deleting the serialized string your are storing in your storage location. Destroy() takes only one argument: the session ID (the value of the PHPSESSID cookie)
GC "GC" stands for "Garbage Collection," it is the function that clears out old stored sessions. It takes a single argument: the maximum session lifetime set in your php.ini file. Your garbage collection function should be designed to destroy ALL sessions older than the lifetime value. Using a self-expiring storage engine like memcache alleviates the need to have a garbage collection function at all, but permanent storage engines like databases and filesystems require cleaning up.
Using this basic framework, you can easily make a custom session handler that uses a specific file location. Check the PHP manual entry for session_set_save_handler() for a quick example of a very basic session handler. Naturally, since the default session handling built into PHP uses filed, the custom filesystem handler is not really all that handy.
Using a MySQL Database as a Storage Engine
By now you should be familiar with the basics of database access. The functionality we need for session management is INSERT, UPDATE, SELECT, and DELETE. First, we need to create a table to store the session data. Remember that the session garbage collection function requires a timestamp on the session data. Therefore, we need three columns in this table.
ID The session ID is a 32 character string. Normally you're probably used to a table's ID being numeric, like from an auto-incrememt column, but since PHP creates this string for you, use it as the primary ID. There is no real threat of collision. Make this field varchar(32)
CONTENTS The session contents are a string of variable length. Depending on how much data you plan to put into the session, it can be quite large. For this reason, the session contents should be a BLOB.
UPDATE_DATE The most recent date the session was modified needs to be stored along with the session data so that the garbage collection function knows which sessions to destroy.
CREATE TABLE EXAMPLE CREATE TABLE `sessions` ( `id` varchar(32) NOT NULL, `contents` blob, `modify_date` datetime NOT NULL, PRIMARY KEY (`id`), KEY `modify_date` (`modify_date`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8