Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id)); /* it is possible that the update statement fails due to a collision */ if (!$ok) { session_id($old_id); if (empty($ck)) $ck = session_get_cookie_params(); setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure'], $ck['httponly']); return false; } return true; } /** * Generate database table for session data. * @see PHPLens Issue No: 12280 * * @return int 0 if failure, 1 if errors, 2 if successful. * * @author Markus Staab http://www.public-4u.de */ function adodb_session_create_table($schemaFile=null,$conn = null) { // set default values if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml'; if ($conn===null) $conn = ADODB_Session::_conn(); if (!$conn) return 0; $schema = new adoSchema($conn); $schema->ParseSchema($schemaFile); return $schema->ExecuteSchema(); } /** * ADOdb Session v2 class. */ class ADODB_Session { /** * Session Connection's Database provider. * * Populated when opening the database connection. * @see ADODB_Session::open()}. * * @var string */ protected static $provider; ///////////////////// // getter/setter methods ///////////////////// /** * Get/Set Database driver. * * @param string $driver * @return string */ static function driver($driver = null) { static $_driver = 'mysqli'; static $set = false; if (!is_null($driver)) { $_driver = trim($driver); $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) { return $GLOBALS['ADODB_SESSION_DRIVER']; } } return $_driver; } /** * Get/Set Database hostname. * * @param string $host * @return string */ static function host($host = null) { static $_host = 'localhost'; static $set = false; if (!is_null($host)) { $_host = trim($host); $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) { return $GLOBALS['ADODB_SESSION_CONNECT']; } } return $_host; } /** * Get/Set Database connection user. * * @param string $user * @return string */ static function user($user = null) { static $_user = 'root'; static $set = false; if (!is_null($user)) { $_user = trim($user); $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESSION_USER'])) { return $GLOBALS['ADODB_SESSION_USER']; } } return $_user; } /** * Get/Set Database connection password. * * @param null $password * @return string */ static function password($password = null) { static $_password = ''; static $set = false; if (!is_null($password)) { $_password = $password; $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESSION_PWD'])) { return $GLOBALS['ADODB_SESSION_PWD']; } } return $_password; } /** * Get/Set Database name. * * @param null $database * @return string */ static function database($database = null) { static $_database = ''; static $set = false; if (!is_null($database)) { $_database = trim($database); $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESSION_DB'])) { return $GLOBALS['ADODB_SESSION_DB']; } } return $_database; } /** * Get/Set Connection's persistence mode. * * @param $persist * @return string|true */ static function persist($persist = null) { static $_persist = true; if (!is_null($persist)) { $_persist = trim($persist); } return $_persist; } /** * Get/Set Connection's lifetime. * * @param int $lifetime * @return int */ static function lifetime($lifetime = null) { static $_lifetime; static $set = false; if (!is_null($lifetime)) { $_lifetime = (int) $lifetime; $set = true; } elseif (!$set) { // backwards compatibility if (isset($GLOBALS['ADODB_SESS_LIFE'])) { return $GLOBALS['ADODB_SESS_LIFE']; } } if (!$_lifetime) { $_lifetime = ini_get('session.gc_maxlifetime'); if ($_lifetime <= 1) { // bug in PHP 4.0.3 pl 1 -- how about other versions? //print "
Session: connection failed
', false); return $ok; } /** * Close the connection */ static function close() { /* $conn = ADODB_Session::_conn(); if ($conn) $conn->Close(); */ return true; } /** * Slurp in the session variables and return the serialized string. * * @param string $key * @return string */ static function read($key) { $conn = ADODB_Session::_conn(); $filter = ADODB_Session::filter(); $table = ADODB_Session::table(); if (!$conn) { return ''; } $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; global $ADODB_SESSION_SELECT_FIELDS; if (!isset($ADODB_SESSION_SELECT_FIELDS)) $ADODB_SESSION_SELECT_FIELDS = 'sessdata'; $sql = "SELECT $ADODB_SESSION_SELECT_FIELDS FROM $table WHERE sesskey = $binary ".$conn->Param(0)." AND expiry >= " . $conn->sysTimeStamp; /* Lock code does not work as it needs to hold transaction within whole page, and we don't know if developer has committed elsewhere... :( */ #if (ADODB_Session::Lock()) # $rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata); #else $rs = $conn->Execute($sql, array($key)); //ADODB_Session::_dumprs($rs); if ($rs) { if ($rs->EOF) { $v = ''; } else { $v = reset($rs->fields); $filter = array_reverse($filter); foreach ($filter as $f) { if (is_object($f)) { $v = $f->read($v, ADODB_Session::_sessionKey()); } } $v = rawurldecode($v); } $rs->Close(); ADODB_Session::_crc(strlen($v) . crc32($v)); return $v; } return ''; } /** * Write the serialized data to a database. * * If the data has not been modified since the last read(), we do not write. * * @param string $key * @param string $oval * * @return bool */ static function write($key, $oval) { global $ADODB_SESSION_READONLY; if (!empty($ADODB_SESSION_READONLY)) { return false; } $clob = ADODB_Session::clob(); $conn = ADODB_Session::_conn(); $crc = ADODB_Session::_crc(); $debug = ADODB_Session::debug(); $driver = ADODB_Session::driver(); $expire_notify = ADODB_Session::expireNotify(); $filter = ADODB_Session::filter(); $lifetime = ADODB_Session::lifetime(); $table = ADODB_Session::table(); if (!$conn) { return false; } if ($debug) $conn->debug = 1; $sysTimeStamp = $conn->sysTimeStamp; $expiry = $conn->OffsetDate($lifetime/(24*3600),$sysTimeStamp); $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; // crc32 optimization since adodb 2.1 // now we only update expiry date, thx to sebastian thom in adodb 2.32 if ($crc !== '00' && $crc !== false && $crc == (strlen($oval) . crc32($oval))) { if ($debug) { echo 'Session: Only updating date - crc32 not changed
'; } $expirevar = ''; if ($expire_notify) { $var = reset($expire_notify); global $$var; if (isset($$var)) { $expirevar = $$var; } } $sql = "UPDATE $table SET expiry = $expiry, expireref=" . $conn->Param('0') . ", modified = $sysTimeStamp WHERE sesskey = $binary " . $conn->Param('1') . " AND expiry >= $sysTimeStamp"; $rs = $conn->Execute($sql,array($expirevar,$key)); return true; } $val = rawurlencode($oval); foreach ($filter as $f) { if (is_object($f)) { $val = $f->write($val, ADODB_Session::_sessionKey()); } } $expireref = ''; if ($expire_notify) { $var = reset($expire_notify); global $$var; if (isset($$var)) { $expireref = $$var; } } if (!$clob) { // no lobs, simply use replace() $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key)); if ($rs) $rs->Close(); if ($rs && reset($rs->fields) > 0) { $sql = "UPDATE $table SET expiry=$expiry, sessdata=".$conn->Param(0).", expireref= ".$conn->Param(1).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param(2); } else { $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified) VALUES ($expiry,".$conn->Param('0').", ". $conn->Param('1').", ".$conn->Param('2').", $sysTimeStamp, $sysTimeStamp)"; } $rs = $conn->Execute($sql,array($val,$expireref,$key)); } else { // what value shall we insert/update for lob row? if (strncmp($driver, 'oci8', 4) == 0) $lob_value = sprintf('empty_%s()', strtolower($clob)); else $lob_value = 'null'; $conn->StartTrans(); $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key)); if ($rs && reset($rs->fields) > 0) { $sql = "UPDATE $table SET expiry=$expiry, sessdata=$lob_value, expireref= ".$conn->Param(0).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('1'); } else { $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified) VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)"; } $conn->Execute($sql,array($expireref,$key)); $qkey = $conn->qstr($key); $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob)); if ($debug) echo "Session Replace: ' . $conn->ErrorMsg() . '
', false); return false; } else { // bug in access driver (could be odbc?) means that info is not committed // properly unless select statement executed in Win2000 if ($conn->databaseType == 'access') { $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey"; $rs = $conn->Execute($sql); ADODB_Session::_dumprs($rs); if ($rs) { $rs->Close(); } } }/* if (ADODB_Session::Lock()) { $conn->CommitTrans(); }*/ return $rs ? true : false; } /** * Destroy session. * * @param string $key * @return bool */ static function destroy($key) { $conn = ADODB_Session::_conn(); $table = ADODB_Session::table(); $expire_notify = ADODB_Session::expireNotify(); if (!$conn) { return false; } $debug = ADODB_Session::debug(); if ($debug) $conn->debug = 1; $qkey = $conn->quote($key); $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; if ($expire_notify) { reset($expire_notify); $fn = next($expire_notify); $savem = $conn->SetFetchMode(ADODB_FETCH_NUM); $sql = "SELECT expireref, sesskey FROM $table WHERE sesskey = $binary $qkey"; $rs = $conn->Execute($sql); ADODB_Session::_dumprs($rs); $conn->SetFetchMode($savem); if (!$rs) { return false; } if (!$rs->EOF) { $ref = $rs->fields[0]; $key = $rs->fields[1]; $fn($ref, $key); } $rs->Close(); } $sql = "DELETE FROM $table WHERE sesskey = $binary $qkey"; $rs = $conn->Execute($sql); if ($rs) { $rs->Close(); } return (bool)$rs; } /** * Perform garbage collection. * * @param int $maxlifetime * @return bool */ static function gc($maxlifetime) { $conn = ADODB_Session::_conn(); $debug = ADODB_Session::debug(); $expire_notify = ADODB_Session::expireNotify(); $optimize = ADODB_Session::optimize(); $table = ADODB_Session::table(); if (!$conn) { return false; } if ($debug) { $conn->debug = 1; $COMMITNUM = 2; } else { $COMMITNUM = 20; } $time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp); $binary = ADODB_Session::isConnectionMysql() ? '/*! BINARY */' : ''; if ($expire_notify) { reset($expire_notify); $fn = next($expire_notify); } else { $fn = false; } $savem = $conn->SetFetchMode(ADODB_FETCH_NUM); $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time ORDER BY 2"; # add order by to prevent deadlock $rs = $conn->SelectLimit($sql,1000); if ($debug) ADODB_Session::_dumprs($rs); $conn->SetFetchMode($savem); if ($rs) { $tr = $conn->hasTransactions; if ($tr) $conn->BeginTrans(); $ccnt = 0; while (!$rs->EOF) { $ref = $rs->fields[0]; $key = $rs->fields[1]; if ($fn) $fn($ref, $key); $conn->Execute("DELETE FROM $table WHERE sesskey = $binary " . $conn->Param('0'), array($key)); $rs->MoveNext(); $ccnt += 1; if ($tr && $ccnt % $COMMITNUM == 0) { if ($debug) echo "Commit