MySQL sessions are “gotta have it” thing if your site ever grows beyond single server. If you have multiple servers behind a load balancer, you could keep session data on a shared SAN, but MySQL makes for a better session store.
Create a file called MySession.php and put this code in it, replace the definitions to match your database. Also, it requires the PEAR DB.php module, make sure you have pear DB installed: pear install DB.
<?php /** * MySession.php * * Originally developed by David Koopman * */ /* The MySQL table should look like this: CREATE TABLE `Sessions` ( `session_id` varchar(32) NOT NULL default '', `last_access_time` datetime NOT NULL default '0000-00-00 00:00:00', `data` mediumtext NOT NULL, PRIMARY KEY (`session_id`), KEY `last_access_time` (`last_access_time`) ) TYPE=MyISAM; # You may want to create a MySQL user, like this: grant select,update,insert,delete on mysess.* to mysess@'localhost' identified by 'mysesspassword'; */ require_once("DB.php"); ini_set('session.gc_probability', 1); ini_set('session.gc_divisor', 10000); // active sites only need cleanup 1/10,000 hits ini_set('session.gc_maxlifetime', 60*60*24); // 24 hours ini_set('session.use_cookies', 1); // yes, the prefered method, no URL passing ini_set('session.use_only_cookies', 1); // prevent attacks with session ids in URLs ini_set('session.cookie_lifetime', 0); // the default, when the browser closes ini_set('session.cache_limiter', 'nocache'); ini_set('session.use_trans_sid', 0); define('MY_SESS_DSN', "mysql://mysess:mysesspassword@localhost/mysess"); define('MY_SESS_SQL_READ', "SELECT data FROM Sessions WHERE ( session_id=%s )"); define('MY_SESS_SQL_WRITE', "REPLACE INTO Sessions ( session_id, data, last_access_time ) VALUES ( %s, %s, NOW() )"); define('MY_SESS_SQL_DESTROY', "DELETE FROM Sessions WHERE ( session_id=%s )"); define('MY_SESS_SQL_STALE', "DELETE FROM Sessions WHERE last_access_time < %s"); class MySession { /** * MySession::MySession * * { constructor } * * */ function MySession($id=false) { session_set_save_handler( array( $this, 'sessOpen' ), array( $this, 'sessClose' ), array( $this, 'sessRead' ), array( $this, 'sessWrite' ), array( $this, 'sessDestroy' ), array( $this, 'sessGC' ) ); if ($id) session_id($id); session_start(); } /** * MySession::sessOpen * * ( PRIVATE METHOD: * internal open session ) * */ function sessOpen( $aSavePath, $aSessionName ) { // because of DB storage, this is an unneeded call return true; } /** * MySession::sessClose * * ( PRIVATE METHOD: * internal close session ) * */ function sessClose() { // because of DB storage, this is an unneeded call return true; } /** * MySession::sessRead * * ( PRIVATE METHOD: * internal read session variable ) * */ function sessRead( $aSessionID ) { $sessionDB = DB::connect( MY_SESS_DSN ); if(DB::isError($sessionDB)) { error_log("sessRead DB ERROR: ".DB::errorMessage($sessionDB)); return false; } $sessionDB->setFetchMode( DB_FETCHMODE_ASSOC ); // set up SQL statement $aSQL = sprintf( MY_SESS_SQL_READ, $sessionDB->quote($aSessionID) ); $aResult = $sessionDB->query( $aSQL ); if ( DB::isError( $aResult ) ) { error_log("sessRead DB error, $aSQL ERROR: ".DB::errorMessage($aResult)); return false; } $aRowCount = $aResult->numRows(); // if the session variable exists, return the value if ( is_int($aRowCount) && $aRowCount > 0 ) { $aRow = $aResult->fetchRow(); return $aRow['data']; } else // the session variable has no value { return false; } } /** * MySession::sessWrite * * ( PRIVATE METHOD: * internal write session variable ) * */ function sessWrite( $aSessionID, $aValue ) { $sessionDB = DB::connect( MY_SESS_DSN ); if(DB::isError($sessionDB)) { error_log("sessWrite DB ERROR: ".DB::errorMessage($sessionDB)); return false; } $sessionDB->setFetchMode( DB_FETCHMODE_ASSOC ); $aSQL = sprintf( MY_SESS_SQL_WRITE, $sessionDB->quote($aSessionID), $sessionDB->quote($aValue) ); $aResult = $sessionDB->query( $aSQL ); if ( DB::isError( $aResult ) ) { error_log("sessWrite DB error,$aSQL ERROR: ".DB::errorMessage($aResult)); return false; } // error_log("sessWrite SQL: $aSQL"); return true; } /** * MySession::sessDestroy * * ( PRIVATE METHOD: * internal destroy session ) * */ function sessDestroy( $aSessionID ) { $sessionDB = DB::connect( MY_SESS_DSN ); if(DB::isError($sessionDB)) { error_log("sessRead DB ERROR: ".DB::errorMessage($sessionDB)); return false; } $sessionDB->setFetchMode( DB_FETCHMODE_ASSOC ); $aSQL = sprintf( MY_SESS_SQL_DESTROY, $sessionDB->quote($aSessionID) ); $sessionDB->query( $aSQL ); $_SESSION = array(); return true; } /** * MySession::sessGC * * ( PRIVATE METHOD: * internal cleanup stale sessions ) * */ function sessGC( $aMaxLifetime ) { $sessionDB = DB::connect( MY_SESS_DSN ); if(DB::isError($sessionDB)) { error_log("sessRead DB ERROR: ".DB::errorMessage($sessionDB)); return false; } $sessionDB->setFetchMode( DB_FETCHMODE_ASSOC ); $aSQL = sprintf( MY_SESS_SQL_STALE, $sessionDB->quote(Date("Y-m-d H:i:s", time()-$aMaxLifetime)) ); $sessionDB->query( $aSQL ); return true; } }
To use it is simple, instead of calling session_start(), just include the MySession class and call new MySession(); to start the session. From there, just use the $_SESSION variable.
<?php
require_once("MySession.php");
new MySession();
$_SESSION[‘test’]++;
print $_SESSION[‘test’];
Comments are closed.