[ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 /** 3 * PostgreSQL Session Handler for PHP (native). 4 * 5 * Copyright 2000-2006 Jon Parise <jon@csh.rit.edu>. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * Required parameters:<pre> 29 * 'database' The name of the database. 30 * 'password' The password associated with 'username'. 31 * 'protocol' The communication protocol ('tcp', 'unix'). 32 * 'username' The username with which to connect to the database. 33 * 34 * Required for some configurations (i.e. 'protocol' = 'tcp'):<pre> 35 * 'hostspec' The hostname of the database server. 36 * 'port' The port on which to connect to the database.</pre> 37 * 38 * Optional parameters:<pre> 39 * 'persistent' Use persistent DB connections? (boolean) 40 * Default: NO 41 * 'table' The name of the sessiondata table in 'database'. 42 * Default: 'horde_sessionhandler'</pre> 43 * 44 * The table structure for the SessionHandler can be found in 45 * horde/scripts/sql/horde_sessionhandler.pgsql.sql. 46 * 47 * Contributors:<pre> 48 * Jason Carlson Return an empty string on failed reads 49 * pat@pcprogrammer.com Perform update in a single transaction 50 * Jonathan Crompton Lock row for life of session</pre> 51 * 52 * $Horde: framework/SessionHandler/SessionHandler/pgsql.php,v 1.12.10.15 2006/03/23 18:00:17 jan Exp $ 53 * 54 * @author Jon Parise <jon@csh.rit.edu> 55 * @since Horde 3.0 56 * @package Horde_SessionHandler 57 */ 58 class SessionHandler_pgsql extends SessionHandler { 59 60 /** 61 * Handle for the current database connection. 62 * 63 * @var resource 64 */ 65 var $_db; 66 67 /** 68 * Are we connected to the SQL server. 69 * 70 * @var boolean 71 */ 72 var $_connected = false; 73 74 /** 75 * Close the SessionHandler backend. 76 * 77 * @return boolean True on success, false otherwise. 78 */ 79 function close() 80 { 81 /* Disconnect from database. */ 82 if ($this->_connected) { 83 $this->_connected = false; 84 return @pg_close($this->_db); 85 } 86 87 return true; 88 } 89 90 /** 91 * Read the data for a particular session identifier from the 92 * SessionHandler backend. 93 * 94 * @param string $id The session identifier. 95 * 96 * @return string The session data. 97 */ 98 function read($id) 99 { 100 /* Make sure we have a valid database connection. */ 101 $this->_connect(); 102 103 @pg_query($this->_db, 'BEGIN;'); 104 105 $timeout = time() - ini_get('session.gc_maxlifetime'); 106 $query = sprintf('SELECT session_data FROM %s WHERE ' . 107 'session_id = %s AND session_lastmodified >= %s ' . 108 'FOR UPDATE;', 109 $this->_params['table'], 110 $this->quote($id), 111 $timeout); 112 113 /* Log the query at a DEBUG log level. */ 114 Horde::logMessage(sprintf('SQL Query by SessionHandler_pgsql::' . 115 'read(): query = "%s"', $query), 116 __FILE__, __LINE__, PEAR_LOG_DEBUG); 117 118 $result = @pg_query($this->_db, $query); 119 $data = pg_fetch_result($result, 0, 'session_data'); 120 pg_free_result($result); 121 122 return pack('H*', $data); 123 } 124 125 /** 126 * Write session data to the SessionHandler backend. 127 * 128 * @param string $id The session identifier. 129 * @param string $session_data The session data. 130 * 131 * @return boolean True on success, false otherwise. 132 */ 133 function write($id, $session_data) 134 { 135 /* Make sure we have a valid database connection. */ 136 $this->_connect(); 137 138 $timeout = time() - ini_get('session.gc_maxlifetime'); 139 $query = sprintf('SELECT session_data FROM %s WHERE ' . 140 'session_id = %s AND session_lastmodified >= %s ' . 141 'FOR UPDATE', 142 $this->_params['table'], 143 $this->quote($id), 144 $timeout); 145 $result = @pg_query($this->_db, $query); 146 $rows = pg_num_rows($result); 147 pg_free_result($result); 148 149 if ($rows == 0) { 150 $query = sprintf('INSERT INTO %s (session_id, ' . 151 'session_lastmodified, session_data) ' . 152 'VALUES (%s, %s, %s);', 153 $this->_params['table'], 154 $this->quote($id), 155 time(), 156 $this->quote(bin2hex($session_data))); 157 } else { 158 $query = sprintf('UPDATE %s SET session_lastmodified = %s, ' . 159 'session_data = %s WHERE session_id = %s;', 160 $this->_params['table'], 161 time(), 162 $this->quote(bin2hex($session_data)), 163 $this->quote($id)); 164 } 165 166 /* Log the query at a DEBUG log level. */ 167 Horde::logMessage(sprintf('SQL Query by SessionHandler_pgsql::' . 168 'write(): query = "%s"', $query), 169 __FILE__, __LINE__, PEAR_LOG_DEBUG); 170 171 $result = @pg_query($this->_db, $query); 172 if (!$result) { 173 Horde::logMessage('Error writing session data: ' . pg_last_error($this->_db), __FILE__, __LINE__, PEAR_LOG_ERR); 174 return false; 175 } 176 $rows = pg_affected_rows($result); 177 pg_free_result($result); 178 179 @pg_query($this->_db, 'COMMIT;'); 180 181 if ($rows != 1) { 182 Horde::logMessage('Error writing session data', 183 __FILE__, __LINE__, PEAR_LOG_ERR); 184 return false; 185 } 186 187 return true; 188 } 189 190 /** 191 * Destroy the data for a particular session identifier in the 192 * SessionHandler backend. 193 * 194 * @param string $id The session identifier. 195 * 196 * @return boolean True on success, false otherwise. 197 */ 198 function destroy($id) 199 { 200 /* Make sure we have a valid database connection. */ 201 $this->_connect(); 202 203 /* Build the SQL query. */ 204 $query = sprintf('DELETE FROM %s WHERE session_id = %s;', 205 $this->_params['table'], $this->quote($id)); 206 207 /* Log the query at a DEBUG log level. */ 208 Horde::logMessage(sprintf('SQL Query by SessionHandler_pgsql::' . 209 'destroy(): query = "%s"', $query), 210 __FILE__, __LINE__, PEAR_LOG_DEBUG); 211 212 /* Execute the query. */ 213 $result = @pg_query($this->_db, $query); 214 215 @pg_query($this->_db, 'COMMIT;'); 216 217 if (!$result) { 218 pg_free_result($result); 219 Horde::logMessage('Failed to delete session (id = ' . $id . ')', 220 __FILE__, __LINE__, PEAR_LOG_ERR); 221 return false; 222 } 223 224 pg_free_result($result); 225 return true; 226 } 227 228 /** 229 * Garbage collect stale sessions from the SessionHandler backend. 230 * 231 * @param integer $maxlifetime The maximum age of a session. 232 * 233 * @return boolean True on success, false otherwise. 234 */ 235 function gc($maxlifetime = 300) 236 { 237 /* Make sure we have a valid database connection. */ 238 $this->_connect(); 239 240 /* Build the SQL query. */ 241 $query = sprintf('DELETE FROM %s WHERE session_lastmodified < %s', 242 $this->_params['table'], 243 $this->quote(time() - $maxlifetime)); 244 245 /* Log the query at a DEBUG log level. */ 246 Horde::logMessage(sprintf('SQL Query by SessionHandler_pgsql::' . 247 'gc(): query = "%s"', $query), 248 __FILE__, __LINE__, PEAR_LOG_DEBUG); 249 250 /* Execute the query. */ 251 $result = @pg_query($this->_db, $query); 252 if (!$result) { 253 Horde::logMessage('Error garbage collecting old sessions', 254 __FILE__, __LINE__, PEAR_LOG_ERR); 255 } 256 257 pg_free_result($result); 258 return $result; 259 } 260 261 /** 262 * Escape a string for insertion into the database. 263 * @access private 264 * 265 * @param string $value The string to quote. 266 * 267 * @return string The quoted string. 268 */ 269 function quote($value) 270 { 271 return "'" . addslashes($value) . "'"; 272 } 273 274 /** 275 * Get a list of the valid session identifiers. 276 * 277 * @return array A list of valid session identifiers. 278 */ 279 function getSessionIDs() 280 { 281 /* Make sure we have a valid database connection. */ 282 $this->_connect(); 283 284 /* Build the SQL query. */ 285 $query = 'SELECT session_id FROM ' . $this->_params['table']; 286 287 /* Log the query at a DEBUG log level. */ 288 Horde::logMessage(sprintf('SQL Query by SessionHandler_pgsql::' . 289 'getSessionIDs(): query = "%s"', $query), 290 __FILE__, __LINE__, PEAR_LOG_DEBUG); 291 292 /* Execute the query. */ 293 $result = @pg_query($this->_db, $query); 294 if (!$result) { 295 pg_free_result($result); 296 Horde::logMessage('Error getting session IDs', 297 __FILE__, __LINE__, PEAR_LOG_ERR); 298 return false; 299 } 300 301 $sessions = array(); 302 while ($row = pg_fetch_row($result)) { 303 $sessions[] = $row[0]; 304 } 305 306 pg_free_result($result); 307 308 return $sessions; 309 } 310 311 /** 312 * Attempts to open a connection to the SQL server. 313 * 314 * @return boolean True on success; exits (Horde::fatal()) on error. 315 */ 316 function _connect() 317 { 318 if (!$this->_connected) { 319 Horde::assertDriverConfig($this->_params, 'sessionhandler', 320 array('hostspec', 'username', 'database', 'password'), 321 'session handler pgsql'); 322 323 if (empty($this->_params['table'])) { 324 $this->_params['table'] = 'horde_sessionhandler'; 325 } 326 327 $connect = empty($this->_params['persistent']) ? 328 'pg_connect' :'pg_pconnect'; 329 330 $paramstr = ''; 331 if (isset($this->_params['protocol']) && 332 $this->_params['protocol'] == 'tcp') { 333 $paramstr .= ' host=' . $this->_params['hostspec']; 334 if (isset($this->_params['port'])) { 335 $paramstr .= ' port=' . $this->_params['port']; 336 } 337 } 338 $paramstr .= ' dbname=' . $this->_params['database'] . 339 ' user=' . $this->_params['username'] . 340 ' password=' . $this->_params['password']; 341 342 if (!$this->_db = @$connect($paramstr)) { 343 return false; 344 } 345 346 $this->_connected = true; 347 } 348 349 return true; 350 } 351 352 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |