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; } } ?>