00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 if (!defined('_ADODB_LAYER')) {
00029 require_once realpath(dirname(__FILE__) . '/../adodb.inc.php');
00030 }
00031
00032 if (defined('ADODB_SESSION')) return 1;
00033
00034 define('ADODB_SESSION', dirname(__FILE__));
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 function adodb_unserialize( $serialized_string )
00047 {
00048 $variables = array( );
00049 $a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
00050 for( $i = 0; $i < count( $a ); $i = $i+2 ) {
00051 $variables[$a[$i]] = unserialize( $a[$i+1] );
00052 }
00053 return( $variables );
00054 }
00055
00056
00057
00058
00059
00060 function adodb_session_regenerate_id()
00061 {
00062 $conn =& ADODB_Session::_conn();
00063 if (!$conn) return false;
00064
00065 $old_id = session_id();
00066 if (function_exists('session_regenerate_id')) {
00067 session_regenerate_id();
00068 } else {
00069 session_id(md5(uniqid(rand(), true)));
00070 $ck = session_get_cookie_params();
00071 setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
00072
00073 }
00074 $new_id = session_id();
00075 $ok =& $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
00076
00077
00078 if (!$ok) {
00079 session_id($old_id);
00080 if (empty($ck)) $ck = session_get_cookie_params();
00081 setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
00082 return false;
00083 }
00084
00085 return true;
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 function adodb_session_create_table($schemaFile=null,$conn = null)
00095 {
00096
00097 if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema.xml';
00098 if ($conn===null) $conn =& ADODB_Session::_conn();
00099
00100 if (!$conn) return 0;
00101
00102 $schema = new adoSchema($conn);
00103 $schema->ParseSchema($schemaFile);
00104 return $schema->ExecuteSchema();
00105 }
00106
00110 class ADODB_Session {
00112
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00127 function driver($driver = null) {
00128 static $_driver = 'mysql';
00129 static $set = false;
00130
00131 if (!is_null($driver)) {
00132 $_driver = trim($driver);
00133 $set = true;
00134 } elseif (!$set) {
00135
00136 if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
00137 return $GLOBALS['ADODB_SESSION_DRIVER'];
00138 }
00139 }
00140
00141 return $_driver;
00142 }
00143
00146 function host($host = null) {
00147 static $_host = 'localhost';
00148 static $set = false;
00149
00150 if (!is_null($host)) {
00151 $_host = trim($host);
00152 $set = true;
00153 } elseif (!$set) {
00154
00155 if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
00156 return $GLOBALS['ADODB_SESSION_CONNECT'];
00157 }
00158 }
00159
00160 return $_host;
00161 }
00162
00165 function user($user = null) {
00166 static $_user = 'root';
00167 static $set = false;
00168
00169 if (!is_null($user)) {
00170 $_user = trim($user);
00171 $set = true;
00172 } elseif (!$set) {
00173
00174 if (isset($GLOBALS['ADODB_SESSION_USER'])) {
00175 return $GLOBALS['ADODB_SESSION_USER'];
00176 }
00177 }
00178
00179 return $_user;
00180 }
00181
00184 function password($password = null) {
00185 static $_password = '';
00186 static $set = false;
00187
00188 if (!is_null($password)) {
00189 $_password = $password;
00190 $set = true;
00191 } elseif (!$set) {
00192
00193 if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
00194 return $GLOBALS['ADODB_SESSION_PWD'];
00195 }
00196 }
00197
00198 return $_password;
00199 }
00200
00203 function database($database = null) {
00204 static $_database = 'xphplens_2';
00205 static $set = false;
00206
00207 if (!is_null($database)) {
00208 $_database = trim($database);
00209 $set = true;
00210 } elseif (!$set) {
00211
00212 if (isset($GLOBALS['ADODB_SESSION_DB'])) {
00213 return $GLOBALS['ADODB_SESSION_DB'];
00214 }
00215 }
00216
00217 return $_database;
00218 }
00219
00222 function persist($persist = null)
00223 {
00224 static $_persist = true;
00225
00226 if (!is_null($persist)) {
00227 $_persist = trim($persist);
00228 }
00229
00230 return $_persist;
00231 }
00232
00235 function lifetime($lifetime = null) {
00236 static $_lifetime;
00237 static $set = false;
00238
00239 if (!is_null($lifetime)) {
00240 $_lifetime = (int) $lifetime;
00241 $set = true;
00242 } elseif (!$set) {
00243
00244 if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
00245 return $GLOBALS['ADODB_SESS_LIFE'];
00246 }
00247 }
00248 if (!$_lifetime) {
00249 $_lifetime = ini_get('session.gc_maxlifetime');
00250 if ($_lifetime <= 1) {
00251
00252
00253 $_lifetime = 1440;
00254 }
00255 }
00256
00257 return $_lifetime;
00258 }
00259
00262 function debug($debug = null) {
00263 static $_debug = false;
00264 static $set = false;
00265
00266 if (!is_null($debug)) {
00267 $_debug = (bool) $debug;
00268
00269 $conn = ADODB_Session::_conn();
00270 if ($conn) {
00271 $conn->debug = $_debug;
00272 }
00273 $set = true;
00274 } elseif (!$set) {
00275
00276 if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
00277 return $GLOBALS['ADODB_SESS_DEBUG'];
00278 }
00279 }
00280
00281 return $_debug;
00282 }
00283
00286 function expireNotify($expire_notify = null) {
00287 static $_expire_notify;
00288 static $set = false;
00289
00290 if (!is_null($expire_notify)) {
00291 $_expire_notify = $expire_notify;
00292 $set = true;
00293 } elseif (!$set) {
00294
00295 if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
00296 return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
00297 }
00298 }
00299
00300 return $_expire_notify;
00301 }
00302
00305 function table($table = null) {
00306 static $_table = 'sessions';
00307 static $set = false;
00308
00309 if (!is_null($table)) {
00310 $_table = trim($table);
00311 $set = true;
00312 } elseif (!$set) {
00313
00314 if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
00315 return $GLOBALS['ADODB_SESSION_TBL'];
00316 }
00317 }
00318
00319 return $_table;
00320 }
00321
00324 function optimize($optimize = null) {
00325 static $_optimize = false;
00326 static $set = false;
00327
00328 if (!is_null($optimize)) {
00329 $_optimize = (bool) $optimize;
00330 $set = true;
00331 } elseif (!$set) {
00332
00333 if (defined('ADODB_SESSION_OPTIMIZE')) {
00334 return true;
00335 }
00336 }
00337
00338 return $_optimize;
00339 }
00340
00343 function syncSeconds($sync_seconds = null) {
00344 static $_sync_seconds = 60;
00345 static $set = false;
00346
00347 if (!is_null($sync_seconds)) {
00348 $_sync_seconds = (int) $sync_seconds;
00349 $set = true;
00350 } elseif (!$set) {
00351
00352 if (defined('ADODB_SESSION_SYNCH_SECS')) {
00353 return ADODB_SESSION_SYNCH_SECS;
00354 }
00355 }
00356
00357 return $_sync_seconds;
00358 }
00359
00362 function clob($clob = null) {
00363 static $_clob = false;
00364 static $set = false;
00365
00366 if (!is_null($clob)) {
00367 $_clob = strtolower(trim($clob));
00368 $set = true;
00369 } elseif (!$set) {
00370
00371 if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
00372 return $GLOBALS['ADODB_SESSION_USE_LOBS'];
00373 }
00374 }
00375
00376 return $_clob;
00377 }
00378
00381 function dataFieldName($data_field_name = null) {
00382 static $_data_field_name = 'data';
00383
00384 if (!is_null($data_field_name)) {
00385 $_data_field_name = trim($data_field_name);
00386 }
00387
00388 return $_data_field_name;
00389 }
00390
00393 function filter($filter = null) {
00394 static $_filter = array();
00395
00396 if (!is_null($filter)) {
00397 if (!is_array($filter)) {
00398 $filter = array($filter);
00399 }
00400 $_filter = $filter;
00401 }
00402
00403 return $_filter;
00404 }
00405
00408 function encryptionKey($encryption_key = null) {
00409 static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
00410
00411 if (!is_null($encryption_key)) {
00412 $_encryption_key = $encryption_key;
00413 }
00414
00415 return $_encryption_key;
00416 }
00417
00419
00421
00424 function &_conn($conn=null) {
00425 return $GLOBALS['ADODB_SESS_CONN'];
00426 }
00427
00430 function _crc($crc = null) {
00431 static $_crc = false;
00432
00433 if (!is_null($crc)) {
00434 $_crc = $crc;
00435 }
00436
00437 return $_crc;
00438 }
00439
00442 function _init() {
00443 session_module_name('user');
00444 session_set_save_handler(
00445 array('ADODB_Session', 'open'),
00446 array('ADODB_Session', 'close'),
00447 array('ADODB_Session', 'read'),
00448 array('ADODB_Session', 'write'),
00449 array('ADODB_Session', 'destroy'),
00450 array('ADODB_Session', 'gc')
00451 );
00452 }
00453
00454
00457 function _sessionKey() {
00458
00459
00460 return crypt(ADODB_Session::encryptionKey(), session_id());
00461 }
00462
00465 function _dumprs($rs) {
00466 $conn =& ADODB_Session::_conn();
00467 $debug = ADODB_Session::debug();
00468
00469 if (!$conn) {
00470 return;
00471 }
00472
00473 if (!$debug) {
00474 return;
00475 }
00476
00477 if (!$rs) {
00478 echo "<br />\$rs is null or false<br />\n";
00479 return;
00480 }
00481
00482
00483
00484 if (!is_object($rs)) {
00485 return;
00486 }
00487
00488 require_once ADODB_SESSION.'/../tohtml.inc.php';
00489 rs2html($rs);
00490 }
00491
00493
00495
00501 function open($save_path, $session_name, $persist = null) {
00502 $conn =& ADODB_Session::_conn();
00503
00504 if ($conn) {
00505 return true;
00506 }
00507
00508 $database = ADODB_Session::database();
00509 $debug = ADODB_Session::debug();
00510 $driver = ADODB_Session::driver();
00511 $host = ADODB_Session::host();
00512 $password = ADODB_Session::password();
00513 $user = ADODB_Session::user();
00514
00515 if (!is_null($persist)) {
00516 ADODB_Session::persist($persist);
00517 } else {
00518 $persist = ADODB_Session::persist();
00519 }
00520
00521 # these can all be defaulted to in php.ini
00522 # assert('$database');
00523 # assert('$driver');
00524 # assert('$host');
00525
00526
00527 $conn =& ADONewConnection($driver);
00528
00529 if ($debug) {
00530 $conn->debug = true;
00531
00532 }
00533
00534 if ($persist) {
00535 switch($persist) {
00536 default:
00537 case 'P': $ok = $conn->PConnect($host, $user, $password, $database); break;
00538 case 'C': $ok = $conn->Connect($host, $user, $password, $database); break;
00539 case 'N': $ok = $conn->NConnect($host, $user, $password, $database); break;
00540 }
00541 } else {
00542 $ok = $conn->Connect($host, $user, $password, $database);
00543 }
00544
00545 if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
00546 else
00547 ADOConnection::outp('<p>Session: connection failed</p>', false);
00548
00549
00550 return $ok;
00551 }
00552
00556 function close() {
00557
00558
00559
00560
00561 return true;
00562 }
00563
00564
00565
00566
00567 function read($key) {
00568 $conn =& ADODB_Session::_conn();
00569 $data = ADODB_Session::dataFieldName();
00570 $filter = ADODB_Session::filter();
00571 $table = ADODB_Session::table();
00572
00573 if (!$conn) {
00574 return '';
00575 }
00576
00577 assert('$table');
00578
00579 $qkey = $conn->quote($key);
00580 $binary = $conn->dataProvider === 'mysql' ? '' : '';
00581
00582 $sql = "SELECT $data FROM $table WHERE sesskey = $binary $qkey AND expiry >= " . time();
00583
00584
00585
00586 #if (ADODB_Session::Lock())
00587 # $rs =& $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), $data);
00588 #else
00589
00590 $rs =& $conn->Execute($sql);
00591
00592 if ($rs) {
00593 if ($rs->EOF) {
00594 $v = '';
00595 } else {
00596 $v = reset($rs->fields);
00597 $filter = array_reverse($filter);
00598 foreach ($filter as $f) {
00599 if (is_object($f)) {
00600 $v = $f->read($v, ADODB_Session::_sessionKey());
00601 }
00602 }
00603 $v = rawurldecode($v);
00604 }
00605
00606 $rs->Close();
00607
00608 ADODB_Session::_crc(strlen($v) . crc32($v));
00609 return $v;
00610 }
00611
00612 return '';
00613 }
00614
00620 function write($key, $val) {
00621 $clob = ADODB_Session::clob();
00622 $conn =& ADODB_Session::_conn();
00623 $crc = ADODB_Session::_crc();
00624 $data = ADODB_Session::dataFieldName();
00625 $debug = ADODB_Session::debug();
00626 $driver = ADODB_Session::driver();
00627 $expire_notify = ADODB_Session::expireNotify();
00628 $filter = ADODB_Session::filter();
00629 $lifetime = ADODB_Session::lifetime();
00630 $table = ADODB_Session::table();
00631
00632 if (!$conn) {
00633 return false;
00634 }
00635 $qkey = $conn->qstr($key);
00636
00637 assert('$table');
00638
00639 $expiry = time() + $lifetime;
00640
00641 $binary = $conn->dataProvider === 'mysql' ? '' : '';
00642
00643
00644
00645 if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
00646 if ($debug) {
00647 echo '<p>Session: Only updating date - crc32 not changed</p>';
00648 }
00649 $sql = "UPDATE $table SET expiry = ".$conn->Param('0')." WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= ".$conn->Param('2');
00650 $rs =& $conn->Execute($sql,array($expiry,$key,time()));
00651 ADODB_Session::_dumprs($rs);
00652 if ($rs) {
00653 $rs->Close();
00654 }
00655 return true;
00656 }
00657 $val = rawurlencode($val);
00658 foreach ($filter as $f) {
00659 if (is_object($f)) {
00660 $val = $f->write($val, ADODB_Session::_sessionKey());
00661 }
00662 }
00663
00664 $arr = array('sesskey' => $key, 'expiry' => $expiry, $data => $val, 'expireref' => '');
00665 if ($expire_notify) {
00666 $var = reset($expire_notify);
00667 global $$var;
00668 if (isset($$var)) {
00669 $arr['expireref'] = $$var;
00670 }
00671 }
00672
00673 if (!$clob) {
00674 $arr[$data] = $conn->qstr($val);
00675 $rs = $conn->Replace($table, $arr, 'sesskey', $autoQuote = true);
00676 ADODB_Session::_dumprs($rs);
00677 } else {
00678
00679 switch ($driver) {
00680
00681 case 'oracle':
00682 case 'oci8':
00683 case 'oci8po':
00684 case 'oci805':
00685 $lob_value = sprintf('empty_%s()', strtolower($clob));
00686 break;
00687
00688
00689 default:
00690 $lob_value = 'null';
00691 break;
00692 }
00693
00694
00695 $rs =& $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = $qkey");
00696 ADODB_Session::_dumprs($rs);
00697 if ($rs && reset($rs->fields) > 0) {
00698 $sql = "UPDATE $table SET expiry = $expiry, $data = $lob_value WHERE sesskey = $qkey";
00699 } else {
00700 $sql = "INSERT INTO $table (expiry, $data, sesskey) VALUES ($expiry, $lob_value, $qkey)";
00701 }
00702 if ($rs) {
00703 $rs->Close();
00704 }
00705
00706 $err = '';
00707 $rs1 =& $conn->Execute($sql);
00708 ADODB_Session::_dumprs($rs1);
00709 if (!$rs1) {
00710 $err = $conn->ErrorMsg()."\n";
00711 }
00712 $rs2 =& $conn->UpdateBlob($table, $data, $val, " sesskey=$qkey", strtoupper($clob));
00713 ADODB_Session::_dumprs($rs2);
00714 if (!$rs2) {
00715 $err .= $conn->ErrorMsg()."\n";
00716 }
00717 $rs = ($rs && $rs2) ? true : false;
00718 if ($rs1) {
00719 $rs1->Close();
00720 }
00721 if (is_object($rs2)) {
00722 $rs2->Close();
00723 }
00724 }
00725
00726 if (!$rs) {
00727 ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
00728 return false;
00729 } else {
00730
00731
00732 if ($conn->databaseType == 'access') {
00733 $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
00734 $rs =& $conn->Execute($sql);
00735 ADODB_Session::_dumprs($rs);
00736 if ($rs) {
00737 $rs->Close();
00738 }
00739 }
00740 }
00741
00742
00743
00744 return $rs ? true : false;
00745 }
00746
00749 function destroy($key) {
00750 $conn =& ADODB_Session::_conn();
00751 $table = ADODB_Session::table();
00752 $expire_notify = ADODB_Session::expireNotify();
00753
00754 if (!$conn) {
00755 return false;
00756 }
00757
00758 assert('$table');
00759
00760 $qkey = $conn->quote($key);
00761 $binary = $conn->dataProvider === 'mysql' ? '' : '';
00762
00763 if ($expire_notify) {
00764 reset($expire_notify);
00765 $fn = next($expire_notify);
00766 $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
00767 $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
00768 $rs =& $conn->Execute($sql);
00769 ADODB_Session::_dumprs($rs);
00770 $conn->SetFetchMode($savem);
00771 if (!$rs) {
00772 return false;
00773 }
00774 if (!$rs->EOF) {
00775 $ref = $rs->fields[0];
00776 $key = $rs->fields[1];
00777
00778
00779 $fn($ref, $key);
00780 }
00781 $rs->Close();
00782 }
00783
00784 $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
00785 $rs =& $conn->Execute($sql);
00786 ADODB_Session::_dumprs($rs);
00787 if ($rs) {
00788 $rs->Close();
00789 }
00790
00791 return $rs ? true : false;
00792 }
00793
00796 function gc($maxlifetime) {
00797 $conn =& ADODB_Session::_conn();
00798 $debug = ADODB_Session::debug();
00799 $expire_notify = ADODB_Session::expireNotify();
00800 $optimize = ADODB_Session::optimize();
00801 $sync_seconds = ADODB_Session::syncSeconds();
00802 $table = ADODB_Session::table();
00803
00804 if (!$conn) {
00805 return false;
00806 }
00807
00808 assert('$table');
00809
00810 $time = time();
00811
00812 $binary = $conn->dataProvider === 'mysql' ? '' : '';
00813
00814 if ($expire_notify) {
00815 reset($expire_notify);
00816 $fn = next($expire_notify);
00817 $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
00818 $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time";
00819 $rs =& $conn->Execute($sql);
00820 ADODB_Session::_dumprs($rs);
00821 $conn->SetFetchMode($savem);
00822 if ($rs) {
00823 $conn->BeginTrans();
00824 $keys = array();
00825 while (!$rs->EOF) {
00826 $ref = $rs->fields[0];
00827 $key = $rs->fields[1];
00828 $fn($ref, $key);
00829 $del = $conn->Execute("DELETE FROM $table WHERE sesskey='$key'");
00830 $rs->MoveNext();
00831 }
00832 $rs->Close();
00833
00834 $conn->CommitTrans();
00835 }
00836 } else {
00837
00838 if (1) {
00839 $sql = "SELECT sesskey FROM $table WHERE expiry < $time";
00840 $arr =& $conn->GetAll($sql);
00841 foreach ($arr as $row) {
00842 $sql2 = "DELETE FROM $table WHERE sesskey='$row[0]'";
00843 $conn->Execute($sql2);
00844 }
00845 } else {
00846 $sql = "DELETE FROM $table WHERE expiry < $time";
00847 $rs =& $conn->Execute($sql);
00848 ADODB_Session::_dumprs($rs);
00849 if ($rs) $rs->Close();
00850 }
00851 if ($debug) {
00852 ADOConnection::outp("<p><b>Garbage Collection</b>: $sql</p>");
00853 }
00854 }
00855
00856
00857 if ($optimize) {
00858 $driver = ADODB_Session::driver();
00859
00860 if (preg_match('/mysql/i', $driver)) {
00861 $sql = "OPTIMIZE TABLE $table";
00862 }
00863 if (preg_match('/postgres/i', $driver)) {
00864 $sql = "VACUUM $table";
00865 }
00866 if (!empty($sql)) {
00867 $conn->Execute($sql);
00868 }
00869 }
00870
00871 if ($sync_seconds) {
00872 $sql = 'SELECT ';
00873 if ($conn->dataProvider === 'oci8') {
00874 $sql .= "TO_CHAR({$conn->sysTimeStamp}, 'RRRR-MM-DD HH24:MI:SS')";
00875 } else {
00876 $sql .= $conn->sysTimeStamp;
00877 }
00878 $sql .= " FROM $table";
00879
00880 $rs =& $conn->SelectLimit($sql, 1);
00881 if ($rs && !$rs->EOF) {
00882 $dbts = reset($rs->fields);
00883 $rs->Close();
00884 $dbt = $conn->UnixTimeStamp($dbts);
00885 $t = time();
00886
00887 if (abs($dbt - $t) >= $sync_seconds) {
00888 $msg = __FILE__ .
00889 ": Server time for webserver {$_SERVER['HTTP_HOST']} not in synch with database: " .
00890 " database=$dbt ($dbts), webserver=$t (diff=". (abs($dbt - $t) / 60) . ' minutes)';
00891 error_log($msg);
00892 if ($debug) {
00893 ADOConnection::outp("<p>$msg</p>");
00894 }
00895 }
00896 }
00897 }
00898
00899 return true;
00900 }
00901 }
00902
00903 ADODB_Session::_init();
00904 register_shutdown_function('session_write_close');
00905
00906
00907 function adodb_sess_open($save_path, $session_name, $persist = true) {
00908 return ADODB_Session::open($save_path, $session_name, $persist);
00909 }
00910
00911
00912 function adodb_sess_gc($t)
00913 {
00914 return ADODB_Session::gc($t);
00915 }
00916
00917 ?>