email protected>>
##
## Modified by Barend Scholtus for PHP4 Session Data Storage
##
## PHP4 Session Data Storage Container using a SQL database
##
class SH_Sql {
##
## Define these parameters by overwriting or by
## deriving your own class from it (recommended)
##
var $database_table = "active_sessions";
var $database_class = "DB_Sql";
## end of configuration
var $save_path = "";
var $session_name = "PHPSESSID";
var $db;
function start() {
// do not move these calls to one of the handler functions,
// it won't work with the patched php403pl1 release!
$name = $this->database_class;
$this->db = new $name;
// Install the custom session data save handler
session_set_save_handler (
array($this, "ac_start"),
array($this, "ac_close"),
array($this, "ac_get_value"),
array($this, "ac_store"),
array($this, "ac_delete"),
array($this, "ac_gc"));
}
function ac_start($save_path, $session_name) {
// the two calls wont work with the php403pl1 patch also
$this->save_path = $save_path;
$this->session_name = addslashes($session_name);
return true;
}
function ac_close() {
// how to close a db?
return true;
}
function ac_get_value($id) {
$this->db->query(sprintf("select val from %s where sid = '%s' and name = '%s'",
$this->database_table,
$id,
$this->session_name));
if ($this->db->next_record()) {
$str = $this->db->f("val");
$str = session_decode($str);
return $str;
}
return false;
}
function ac_store($id, $str) {
$str = session_encode($str);
## update duration of visit
$now = date("YmdHis", time());
$uquery = sprintf("update %s set val='%s', changed='%s' where sid='%s' and name='%s'",
$this->database_table,
$str,
$now,
$id,
$this->session_name);
$squery = sprintf("select count(*) from %s where val='%s' and changed='%s' and sid='%s' and name='%s'",
$this->database_table,
$str,
$now,
$id,
$this->session_name);
$iquery = sprintf("insert into %s ( sid, name, val, changed ) values ('%s', '%s', '%s', '%s')",
$this->database_table,
$id,
$this->session_name,
$str,
$now);
$this->db->query($uquery);
# FIRST test to see if any rows were affected.
# Zero rows affected could mean either there were no matching rows
# whatsoever, OR that the update statement did match a row but made
# no changes to the table data (i.e. UPDATE tbl SET col = 'x', when
# "col" is _already_ set to 'x') so then,
# SECOND, query(SELECT...) on the sid to determine if the row is in
# fact there,
# THIRD, verify that there is at least one row present, and if there
# is not, then
# FOURTH, insert the row as we've determined that it does not exist.
if ( $this->db->affected_rows() == 0
&& $this->db->query($squery)
&& $this->db->f(1) == 0
&& !$this->db->query($iquery)) {
return false;
}
return true;
}
function ac_delete($id) {
$this->db->query(sprintf("delete from %s where name = '%s' and sid = '%s'",
$this->database_table,
$this->session_name,
$id));
return true;
}
function ac_gc($maxlifetime) {
$sqldate = date("YmdHis", (time() - $maxlifetime));
$this->db->query(sprintf("DELETE FROM %s WHERE changed < '%s' AND name = '%s'",
$this->database_table,
$sqldate,
$this->session_name));
return true;
}
}
?>

