Replace the phpsession class with the mysql memory table. you can test the effect on your own.
The code is as follows:
/**
@ Usage: use some other storage method (mysql or memcache) instead of php sessoin
@ Author: lein
@ Version: 1.0
*/
Session_start ();
If (! Isset ($ _ SESSION ['test']) {
$ _ SESSION ['test'] = "123_lein _". date ("Y-m-d H: I: s ");
}
Class session {
// Session data
Private $ data;
// Engine, mysql or memcache
Private $ engine;
// Php session expire time
Private $ sessionexpiredTime;
// Current user's session cookie value
Private $ sessionID;
Public function session ($ engineBase = NULL, $ engineName = 'mysql', $ storage_name = 'php _ session '){
Try {
$ This-> sessionexpiredTime = intval (ini_get ("session. cache_expire") * 60;
} Catch (Exception $ Exception ){
$ This-> sessionexpiredTime = 1200;
}
@ Session_start ();
$ This-> sessionID = session_id ();
$ ClassName = $ engineName. "SessionEngine ";
$ This-> engine = new $ className (
Array (
'Storage _ name' => $ storage_name, // mysql table name or memcahce key which stores data;
'Expire _ time' => $ this-> sessionexpiredTime,
'Data _ too_long_instead_value '=>' {__ data IS * $ * to long __}'
),
$ This-> sessionID,
& $ EngineBase
);
$ This-> init ();
$ This-> engine-> refresh ();
$ This-> engine-> cleanup ();
}
Private function init ()
{
$ This-> data = $ this-> engine-> get ();
If (emptyempty ($ this-> data )&&! Emptyempty ($ _ SESSION )){
$ This-> data =$ _ SESSION;
$ This-> engine-> create (false, $ this-> data );
}
Else if (emptyempty ($ this-> data ))
{
$ This-> engine-> create (false, $ this-> data );
}
}
Private function _ get ($ nm)
{
If (isset ($ this-> data [$ nm]) {
$ R = $ this-> data [$ nm];
Return $ r;
}
Else
{
Return NULL;
}
}
Private function _ set ($ nm, $ val)
{
$ This-> data [$ nm] = $ val;
$ This-> engine-> set (false, $ this-> data );
}
Function _ destruct (){
$ This-> data = NULL;
$ This-> engine-> close ();
$ This-> engine = NULL;
}
}
Interface SessionEngine
{
/*
* Set varibles
* @ Param $ arr array, array (varible name => varible value ,...)
*/
Public function setVariable ($ arr );
/*
* Get session value
* @ Param $ key string
*/
Public function get ($ key = "");
/*
* Set session value
* @ Param $ key string
* @ Param $ value string
*/
Public function set ($ key = "", $ value = "");
/*
* Set session value
* @ Param $ key string
* @ Param $ value string
*/
Public function create ($ key = "", $ value = "");
/*
* Update the session's invalid time
* @ Param $ key string
*/
Public function refresh ($ key = "");
/*
* Close mysql or memcache connection
*/
Public function close ();
/*
* Delete expired sessions
*/
Public function cleanup ();
}
Final class mysqlSessionEngine implements SessionEngine {
Private $ id = "";
Private $ storage_name = 'php _ session ';
Private $ storage_name_slow = 'php _ session_slow ';
Private $ data_too_long_instead_value = '{__ data is ~ To long __} '; // if data is longer than $ max_session_data_length and you are using mysql 4 or below, insert this value into memery table instead.
Private $ expire_time = 1200;
Private $ max_session_data_length = 2048;
Private $ conn;
Private $ mysql_version;
Public function mysqlSessionEngine ($ arr = array (), $ key = "", & $ _ conn ){
$ This-> setVariable ($ arr );
$ This-> id = $ key;
If (emptyempty ($ this-> id) | strlen ($ this-> id )! = 32 ){
Throw new Exception (_ FILE __. "-> ". _ LINE __. ": Session's cookie name can't be empty and it must have just 32 charactors! ");
}
$ This-> conn =$ _ conn;
If (! $ This-> conn |! Is_resource ($ this-> conn )){
Throw new Exception (_ FILE _. "->". _ LINE _. ": Need a mysql connection! ");
}
$ This-> mysql_version = $ this-> getOne ("select floor (version ())");
If ($ this-> mysql_version <5 ){
$ This-> max_session_data_length = 255;
}
}
Public function setVariable ($ arr ){
If (! Emptyempty ($ arr) & is_array ($ arr )){
Foreach ($ arr as $ k =>$ v ){
$ This-> $ k = $ v;
If ($ k = 'Storage _ name '){
$ This-> storage_name_slow = $ v. '_ slow ';
}
}
}
}
Public function get ($ key = ""){
If ($ key = "") $ key = $ this-> id;
$ Return = $ this-> getOne ('select value from '. $ this-> storage_name. 'where id = "'. $ key .'"');
If ($ return = $ this-> data_too_long_instead_value)
{
$ Return = $ this-> getOne ('select value from '. $ this-> storage_name_slow. 'where id = "'. $ key .'"');
}
If (! $ Return)
{
$ MysqlError = mysql_error ($ this-> conn );
If (strpos ($ mysqlError, "doesn't exist ")! = False)
{
$ This-> initTable ();
}
$ Return = array ();
}
Else
{
$ Return = unserialize ($ return );
}
Return $ return;
}
Public function close (){
@ Mysql_close ($ this-> conn );
}
Public function cleanup (){
If ($ this-> mysql_version> 4 ){
$ SQL = 'delete from'. $ this-> storage_name. 'while date_add (time, INTERVAL'. $ this-> expire_time. 'second) } Else {
$ SQL = 'delete from'. $ this-> storage_name. 'While time + '. $ this-> expire_time .' }
$ This-> execute ($ SQL );
}
Public function refresh ($ key = ""){
If ($ this-> mysql_version> 4 ){
$ SQL = 'update'. $ this-> storage_name. 'set time = CURRENT_TIMESTAMP () where id = "'. $ key .'"';
} Else {
$ SQL = 'update'. $ this-> storage_name. 'set time = unix_timestamp () where id = "'. $ key .'"';
}
$ Return = $ this-> execute ($ SQL );
If (! $ Return ){
$ This-> initTable ();
$ Return = $ this-> execute ($ SQL, true );
}
Return $ return;
}
Public function create ($ key = "", $ value = ""){
If ($ key = "") $ key = $ this-> id;
If ($ value! = "") $ Value = mysql_real_escape_string (serialize ($ value), $ this-> conn );
If (strlen ($ value)> $ this-> max_session_data_length) throw new Exception (_ FILE __. "-> ". _ LINE __. ": Session data is long than max allow length (". $ this-> max_session_data_length. ")! ");
If ($ this-> mysql_version> 4 ){
$ SQL = 'replace '. $ this-> storage_name. 'set value = \''. $ value. '\', id = "'. $ key. '", time = CURRENT_TIMESTAMP ()';
} Else {
$ SQL = 'replace '. $ this-> storage_name. 'set value = \''. $ value. '\', id = "'. $ key. '", time = unix_timestamp ()';
}
$ Return = $ this-> execute ($ SQL );
If (! $ Return ){
$ This-> initTable ();
$ Return = $ this-> execute ($ SQL, true );
}
Return $ return;
}
Public function set ($ key = "", $ value = ""){
If ($ key = "") $ key = $ this-> id;
If ($ value! = "") $ Value = mysql_real_escape_string (serialize ($ value), $ this-> conn );
$ SQL = 'update'. $ this-> storage_name. 'set value = \ ''. $ value. '\ 'Where id ="'. $ key .'"';
If (strlen ($ value)> $ this-> max_session_data_length)
{
If ($ this-> mysql_version> 4 ){
Throw new Exception (_ FILE __. "-> ". _ LINE __. ": Session data is long than max allow length (". $ this-> max_session_data_length. ")! ");
}
$ SQL = 'replace '. $ this-> storage_name_slow. 'set value = \''. $ value. '\', id = "'. $ key. '", time = unix_timestamp ()';
$ This-> execute ($ SQL, true );
$ SQL = 'update '. $ this-> storage_name. 'set value = \''. $ this-> data_too_long_instead_value. '\ 'Where id = "'. $ key. '"';
}
$ Return = $ this-> execute ($ SQL );
If (! $ Return ){
$ This-> initTable ();
$ Return = $ this-> execute ($ SQL, true );
}
Return $ return;
}
Private function initTable (){
If ($ this-> mysql_version> 4 ){
$ SQL ="
Create table if not exists '". $ this-> storage_name ."'(
'Id' char (32) not null default 'err ',
'Value' VARBINARY (". $ this-> max_session_data_length.") NULL,
'Time' timestamp not null default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
Primary key ('id '),
KEY 'time' ('time ')
) ENGINE = MEMORY;
";
} Else {
$ SqlSlow ="
Create table if not exists '". $ this-> storage_name." _ slow '(
'Id' char (32) not null default 'err ',
'Value' text NULL,
'Time' int (10) not null default '0 ',
Primary key ('id '),
KEY 'time' ('time ')
) ENGINE = MyISAM;
";
$ This-> execute ($ sqlSlow, true );
$ SQL ="
Create table if not exists '". $ this-> storage_name ."'(
'Id' char (32) not null default 'err ',
'Value' VARCHAR (255) NULL,
'Time' int (10) not null default '0 ',
Primary key ('id '),
KEY 'time' ('time ')
) ENGINE = MEMORY;
";
}
Return $ this-> execute ($ SQL, true );
}
Private function execute ($ SQL, $ die = false)
{
If ($ die)
{
Mysql_query ($ SQL, $ this-> conn) or die ("exe SQL error:
". Mysql_error ()."
". $ SQL ."");
}
Else
{
Mysql_query ($ SQL, $ this-> conn );
If (mysql_error ()){
Return false;
} Else {
Return true;
}
}
}
Private function getOne ($ SQL, $ die = false ){
$ Rs = $ this-> query ($ SQL, $ die );
If ($ rs & ($ one = mysql_fetch_row ($ rs ))){
Return $ one [0];
} Else {
Return false;
}
}
Private function query ($ SQL, $ die = false ){
If ($ die)
$ Rs = mysql_query ($ SQL, $ this-> conn) or die ("query SQL error:
". Mysql_error ()."
". $ SQL ."");
Else
$ Rs = mysql_query ($ SQL, $ this-> conn );
Return $ rs;
}
}
$ Lnk = mysql_connect ('localhost', 'root', '123 ')
Or die ('not ccted: '. mysql_error ());
// Make foo the current db
Mysql_select_db ('test', $ lnk) or die ('Can \'t use foo:'. mysql_error ());
$ S = new session ($ lnk );
If (! $ S-> last ){
$ S-> last = time ();
}
Echo "First visit at". $ S-> last ."
";
If (! $ S-> lastv ){
$ S-> lastv = 0;
}
$ S-> lastv ++;
Echo "lastv =". $ S-> lastv ."
";
Echo "test =". $ S-> test ."
";
If (isset ($ _ GET ['Max ']) {
$ S-> boom = str_repeat ("OK", 255 );
}
If (isset ($ _ GET ['boom ']) {
$ S-> boom = $ _ GET ['boom '];
}
Echo "boom =". $ S-> boom ."
";
?>