php, session_set_save_handler & disappearing session vars
| From: | Jason Gerfen | Date: | Thu, 04 Feb 2010 19:11:03 +0000 |
| Subject: | php, session_set_save_handler & disappearing session vars | ||
| Groups: | php.db | ||
| Request: | Send a blank email to php-db+get-46856@lists.php.net to get a copy of this message | ||
I have used session classes before and am at a loss as to why I cannot for the life of me get this to work... Any help is appreciated.
I might just be confused with the database connection handles in order to pull and store session information as there was some information posted on php.net referencing some changes between php4 and php5 in regards to passing a database connection handle to a custom session handler class. However as you can see from the class here it initializes a database connection handle for each function call to *hopefully eliminate this problem.
I do appreciate help on this. Thanks.
First the db sessions table:
CREATE TABLE IF NOT EXISTS
admin_sessions (
session_id varchar(32) NOT NULL default '',
http_user_agent varchar(32) NOT NULL default '',
session_data blob NOT NULL,
session_expire int(11) NOT NULL default '0',
PRIMARY KEY (session_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Pretty simple right? Now here is my dbSessions class (complete with debugging statements:
class dbSession
{
private $data;
private $max_time;
private $dbconn;
public function __construct( $max_time )
{
//@register_shutdown_function( 'session_write_close' );
if( !empty( $max_time ) ) {
@ini_set( 'session.gc_maxlifetime', $max_time );
} else {
@ini_set( 'session.gc_maxlifetime', 3600 );
}
session_set_save_handler(
array( &$this, 'open' ),
array( &$this, 'close' ),
array( &$this, 'read' ),
array( &$this, 'write' ),
array( &$this, 'destroy' ),
array( &$this, 'gc' )
);
//@ini_set('session.gc_probability', 50);
//@ini_set('session.save_handler', 'user');
@register_shutdown_function( 'session_write_close' );
@session_start();
}
public function register( $name, $data )
{
return $_SESSION[$name] = $data;
}
public function open( $path, $name )
{ echo "OPEN CALLED<BR>";
global $defined;
global $handles;
if( ( $this->dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] ) ) !== -1 ) {
return true;//$this->dbconn;
} else {
return false;
}
}
public function close()
{ echo "CLOSE CALLED<BR>";
global $defined;
global $handles;
// clean up data
$handles['misc']->CleanUpVars( $_SESSION, NULL );
// Perform analyze, repair and optimize on used tables$handles['db']->dbFixTable( "admin_sessions", $this->dbconn );
// Free db handle and close connection(s)$handles['db']->dbFreeData( $this->dbconn ); $handles['db']->dbCloseConn( $this->dbconn ); return true; } public function read( $id ) { echo "READ CALLED<BR>"; echo "<pre>"; var_dump( print_r( func_get_args() ) ); echo "</pre>"; global $handles; global $defined; $this->dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] ); $query = "SELECT
session_data FROM admin_sessions WHERE session_id = \"" . $id . "\" AND http_user_agent = \"" . md5( $_SERVER["HTTP_USER_AGENT"] ) . "\" LIMIT 1";
$result = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $this->dbconn ), $this->dbconn );
echo "RAN: " . $query . " => " . $handles['db']->dbNumRowsAffected( $this->dbconn ) . "<br>";
if( ( is_resource( $result ) ) && ( $handles['db']->dbNumRowsAffected( $this->dbconn ) > 0 ) ) {
$fields = $handles['db']->dbArrayResultsAssoc( $result );
echo "FOUND EXISTING SESSION DATA: " . print_r( $fields['session_data'] ) . "<br>";
return stripslashes( $fields['session_data'] );
}
echo "NOTHING FOUND FOR: " . $id . "<br>";
return "";
}
public function write( $id, $data )
{ echo "WRITE CALLED<BR>"; echo "<pre>"; var_dump( print_r( func_get_args() ) ); echo "</pre>";
global $handles;
global $defined;
$this->dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
$query = "SELECT session_data FROM admin_sessions WHERE session_id = \"" . $id . "\" AND http_user_agent = \"" . md5( $_SERVER["HTTP_USER_AGENT"] ) . "\" LIMIT 1";
$result = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $this->dbconn ), $this->dbconn );
//$data = $handles['db']->dbArrayResultsAssoc( $result );
//echo "<pre>"; print_r( $data ); echo "</pre>";
if( ( is_resource( $result ) ) && ( $handles['db']->dbNumRowsAffected( $result ) > 0 ) ) {
$query = "UPDATE admin_sessions SET session_data = \"" . mysql_real_escape_string( $data ) . "\", session_expire = \"" . time() . "\" WHERE session_id = \"" . $id . "\" LIMIT 1";
} else {
$query = "INSERT INTO admin_sessions ( session_id, http_user_agent, session_data, session_expire ) VALUES ( \"" . $id . "\", \"" . md5( $_SERVER["HTTP_USER_AGENT"] ) . "\", \"" . mysql_real_escape_string( $data ) . "\", \"" . time() . "\" ) ON DUPLICATE KEY UPDATE session_data = \"" . mysql_real_escape_string( $data ) . "\", session_expire = \"" . time() . "\"";
}
$result = $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $this->dbconn ), $this->dbconn );
echo "RAN: " . $query . " => " . $handles['db']->dbQuery( $handles['val']->ValidateSQL( $query, $this->dbconn ), $this->dbconn ) . "<br>";
if( ( is_resource( $result ) ) && ( $handles['db']->dbNumRowsAffected( $this->dbconn ) > 0 ) ) {
$fields = $handles['db']->dbArrayResultsAssoc( $result );
return stripslashes( $fields["session_data"] );
}
return "";
}
public function destroy( $id )
{ echo "DESTROY CALLED<BR>";
global $handles;
global $defined;
$this->dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
$query = "DELETE FROM admin_sessions WHERE session_id = \"" . $id . "\" LIMIT 1";
$result = $handles['db']->dbQuery($handles['val']->ValidateSQL($query, $this->dbconn), $this->dbconn);
if( ( is_resource( $result ) ) && ( $handles['db']->dbNumRowsAffected( $this->dbconn ) !== -1 ) ) {
return true;
}
return false;
}
public function gc( $max_time )
{ echo "GC CALLED<BR>";
global $handles;
$this->dbconn = $handles['db']->dbConnect( $defined['dbhost'], $defined['username'], $defined['password'], $defined['dbname'] );
$query = "DELETE FROM admin_sessions WHERE session_expire < \"" . time() - $this->max_time . "\"";
$result = $handles['db']->dbQuery($handles['val']->ValidateSQL($query, $this->dbconn), $this->dbconn);
if( ( is_resource( $result ) ) && ( $handles['db']->dbNumRowsAffected( $this->dbconn ) !== -1 ) ) {
return true;
}
return false;
}
}
And of course the usage:
require 'class.dbsessions.php';
if( empty( $_SESSION['token'] ) ) {
$handles['session'] = new dbSession( $defined['timeout'] );
}
Then once the user has passed a valid authentication mechanism the users session token is set with:
$handles['session']->register( 'token', $token );
--
Jason Gerfen
Systems Administration/Web application development
jason.gerfen@scl.utah.edu
Marriott Library
Lab Systems PC
295 South 1500 East
Salt Lake City, Utah 84112-0806
Ext 5-9810