1 <?php rcs_id('$Id: DbSession.php,v 1.4 2004-02-26 01:38:16 rurban Exp $');
4 * Store sessions data in Pear DB / ADODB ....
8 * Originally by Stanislav Shramko <stanis@movingmail.com>
9 * Minor rewrite by Reini Urban <rurban@x-ray.at> for Phpwiki.
10 * Quasi-major rewrite/decruft/fix by Jeff Dairiki <dairiki@dairiki.org>.
18 * Pear DB handle, or WikiDB object (from which the Pear DB handle will
21 * @param string $table
22 * Name of SQL table containing session data.
24 function DB_Session(&$dbh, $table = 'session') {
25 // Coerce WikiDB to PearDB or ADODB.
26 // Todo: adodb/dba handlers
27 $db_type = $GLOBALS['DBParams']['dbtype'];
28 if (isa($dbh, 'WikiDB')) {
29 $backend = &$dbh->_backend;
30 $db_type = substr(get_class($dbh),7);
31 $class = "DB_Session_".$db_type;
32 if (class_exists($class)) {
33 return new $class(&$backend->_dbh, $table);
34 //return new DB_Session_SQL(&$dbh, $table);
35 //return new DB_Session_ADODB(&$dbh, $table);
38 //Fixme: E_USER_WARNING ignored!
39 trigger_error(sprintf(
40 _("Your WikiDB DB backend '%s' cannot be used for DB_Session. Set USE_DB_SESSION to false."),
41 $db_type), E_USER_WARNING);
49 var $_backend_type = "SQL";
51 function DB_Session_SQL ($dbh, $table) {
54 $this->_table = $table;
56 ini_set('session.save_handler','user');
57 session_module_name('user'); // new style
58 session_set_save_handler(array(&$this, 'do_open'),
59 array(&$this, 'do_close'),
60 array(&$this, 'do_read'),
61 array(&$this, 'do_write'),
62 array(&$this, 'do_destroy'),
63 array(&$this, 'do_gc'));
68 $this->_connected = (bool)$dbh->connection;
69 if (!$this->_connected) {
70 $res = $dbh->connect($dbh->dsn);
71 if (DB::isError($res)) {
72 error_log("PhpWiki::DB_Session::_connect: " . $res->getMessage());
78 function _disconnect() {
79 if (!$this->_connected)
80 $this->_dbh->disconnect();
86 * Actually this function is a fake for session_set_save_handle.
87 * @param string $save_path a path to stored files
88 * @param string $session_name a name of the concrete file
89 * @return boolean true just a variable to notify PHP that everything
93 function do_open ($save_path, $session_name) {
94 //$this->log("_do_open($save_path, $session_name)");
101 * This function is called just after <i>do_write</i> call.
103 * @return boolean true just a variable to notify PHP that everything
107 function do_close() {
108 //$this->log("_do_close()");
113 * Reads the session data from DB.
115 * @param string $id an id of current session
119 function do_read ($id) {
120 //$this->log("_do_read($id)");
121 $dbh = &$this->_connect();
122 $table = $this->_table;
123 $qid = $dbh->quote($id);
125 $res = $dbh->getOne("SELECT sess_data FROM $table WHERE sess_id=$qid");
127 $this->_disconnect();
128 if (DB::isError($res) || empty($res))
130 if (preg_match('|^[a-zA-Z0-9/+=]+$|', $res))
131 $res = base64_decode($res);
136 * Saves the session data into DB.
138 * Just a comment: The "write" handler is not
139 * executed until after the output stream is closed. Thus,
140 * output from debugging statements in the "write" handler
141 * will never be seen in the browser. If debugging output
142 * is necessary, it is suggested that the debug output be
143 * written to a file instead.
146 * @param string $sess_data
147 * @return boolean true if data saved successfully and false
151 function do_write ($id, $sess_data) {
153 $dbh = &$this->_connect();
154 $table = $this->_table;
155 $qid = $dbh->quote($id);
158 // postgres can't handle binary data in a TEXT field.
159 if (isa($dbh, 'DB_pgsql'))
160 $sess_data = base64_encode($sess_data);
161 $qdata = $dbh->quote($sess_data);
163 $res = $dbh->query("UPDATE $table"
164 . " SET sess_data=$qdata, sess_date=$time"
165 . " WHERE sess_id=$qid");
167 if ($dbh->affectedRows() == 0)
168 $res = $dbh->query("INSERT INTO $table"
169 . " (sess_id, sess_data, sess_date)"
170 . " VALUES ($qid, $qdata, $time)");
172 $this->_disconnect();
173 return ! DB::isError($res);
177 * Destroys a session.
179 * Removes a session from the table.
182 * @return boolean true
185 function do_destroy ($id) {
186 $dbh = &$this->_connect();
187 $table = $this->_table;
188 $qid = $dbh->quote($id);
190 $dbh->query("DELETE FROM $table WHERE sess_id=$qid");
192 $this->_disconnect();
197 * Cleans out all expired sessions.
199 * @param int $maxlifetime session's time to live.
200 * @return boolean true
203 function do_gc ($maxlifetime) {
204 $dbh = &$this->_connect();
205 $table = $this->_table;
206 $threshold = time() - $maxlifetime;
208 $dbh->query("DELETE FROM $table WHERE sess_date < $threshold");
210 $this->_disconnect();
216 // adodb-session wrapper: warning! uses different db layout
217 class DB_Session_ADODB_test
220 var $_backend_type = "ADODB";
222 function DB_Session_ADODB_test ($dbh, $table) {
230 // c-hanging-comment-ender-p: nil
231 // indent-tabs-mode: nil