Skip to content

Instantly share code, notes, and snippets.

@SynCap
Last active March 20, 2017 12:19
Show Gist options
  • Save SynCap/ba57f1e8e3637554cd36fba08d4ab7f9 to your computer and use it in GitHub Desktop.
Save SynCap/ba57f1e8e3637554cd36fba08d4ab7f9 to your computer and use it in GitHub Desktop.
Store session data in MySQL database. Incredibly fast then in compare to built-in storage
<?php
/**
* Session Handling Functions using MySQL.
* simply include() this file at the top of any script you wish to use sessions in.
* As long as the table exists in the database, all sessions will be stored in that table.
* This file can be places onto multiple webservers running the same website and they will
* begin to share sessions between them.
*/
define('SESSION_DB_HOST', 'localhost');
define('SESSION_DB_USER', 'user');
define('SESSION_DB_PASS', '');
/**
* Open function is the constructor, it prepares the session connection
*
* @param string $savePath The storage location of the session. Unnecessary for our operations
* @param string $sessionId The ID of the session, unnecessary in the constructor for us
* @return bool
*/
function open( $savePath, $sessionID )
{
// Declare a global session database connection.
global $sessionDB;
// Connect to the database
$sessionDB = mysql_connect( SESSION_DB_HOST, SESSION_DB_USER, SESSION_DB_PASS );
// If the connection was successful...
if ( $sessionDB )
{
// Select the proper database
mysql_select_db( DB, $sessionDB );
// return true so PHP knows it's safe to continue using the session
return true;
}
// If the connection failed, returning false from open() will prevent PHP from
// using the session since it's not working
return false;
}
/**
* The close function destroys the open database connection.
*
* This function is unnecessary for our purposes, since open database connections
* are killed automatically by PHP at the end of scripts.
* However, to be explicit I'm including the proper contents here.
* Note that this function MUST EXIST, but could easily be empty.
*
* @return bool
*/
function close( )
{
// Load the same global session database connection
global $sessionDB;
// destroy the database resource
mysql_close( $sessionDB );
// return true to indicate success
return true;
}
/**
* The read function is what actually loads the session from the database.
*
* @param string $sessionID The 32-character session ID, from $_COOKIE['PHPSESSID']
* @return string
*/
function read( $sessionID )
{
// Use the existing database connection created by open()
global $sessionDB;
// Build the SQL string to select the contents.
// Even though this is a system function, you MUST use mysql_real_escape_string
// because $sessionID comes from a user's cookie and may be malicious
$sql = 'SELECT contents FROM sessions WHERE id = "' . mysql_real_escape_string( $sessionID ) '"';
//execute the query
$rs = mysql_query( $sql, $sessionDB );
//if the query succeeded...
if ( $rs !== false )
{
// fetch the first (and only) row
$row = mysql_fetch_array( $rs );
// return the 'contents' field:
return $row['contents'];
}
// if the query did not succeed, return an empty string
// (which will unserialize to an empty array for a new session)
return '';
}
/**
* The write function writes the existing session data
* to the database AND UPDATES the most recent timestamp
*
* @param string $sessionID The 32-character session ID, from $_COOKIE['PHPSESSID']
* @param string $sessionData The serialized contents of the session
* @return bool
*/
function write( $sessionID, $sessionData )
{
// Use the existing database connection created by open()
global $sessionDB;
// pre-format the variables for mysql since we use them twice:
$sessionID = mysql_real_escape_string( $sessionID );
$sessionData = mysql_real_escape_string( $sessionData );
// Build the SQL statement. Note that since we have the session ID set up
// as a primary key, we can use the INSERT ... ON DUPLICATE KEY UPDATE syntax:
$sql = 'INSERT INTO sessions (id, contents, modify_date) VALUES ("' . $sessionId . '", "' . $sessionData . '", NOW() ) ' .
'ON DUPLICATE KEY UPDATE contents = "' . $sessionData . '", modify_date = NOW()';
// execute the query. If successful, return true
if ( mysql_query( $sql ) )
{
return true;
}
// query failed, return false:
return false;
}
/**
* Destroys the session ID passed in whenever session_destroy() is called by your scripts
*
* @param string $sessionID The 32-character session ID, from $_COOKIE['PHPSESSID']
* @return bool
*/
function destroy( $sessionID )
{
// Use the existing database connection created by open()
global $sessionDB;
// Build the SQL string to delete the contents.
$sql = 'DELETE FROM sessions WHERE id = ' . mysql_real_escape_string( $sessionID );
// execute the query. If successful, return true
if ( mysql_query( $sql ) )
{
return true;
}
// query failed, return false:
return false;
}
/**
* Garbage collection happens at random, and destroys ALL sessions
* older than the lifetime passed in (in seconds)
*
* @param int $sessionMaxLifetime The maximum lifetime (in seconds) of sessions in your storage engine
* @return bool
*/
function garbageCollect( $sessionMaxLifetime )
{
// Use the existing database connection created by open()
global $sessionDB;
// process sessionMaxLifetime, even though it should be trusted from php.ini
$sessionMaxLifetime = intval( $sessionMaxLifetime );
// Build the SQL string to delete the contents.
$sql = 'DELETE FROM sessions WHERE modify_date < DATE_SUB( NOW(), INTERVAL ' . $sessionMaxLifetime . ' seconds )';
// execute the query. If successful, return true
if ( mysql_query( $sql ) )
{
return true;
}
// query failed, return false:
return false;
}
// once all the functions are delcared in the global scope, we can initiate the session handling in PHP:
session_set_save_handler( 'open', 'close', 'read', 'write', 'destroy', 'garbageCollect' );
session_start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment