source: branches/comu-ver2/data/module/adodb/session/old/adodb-session-clob.php @ 18701

Revision 18701, 13.9 KB checked in by nanasess, 14 years ago (diff)

Copyright の更新(#601)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id Revision Date
  • Property svn:mime-type set to text/x-httpd-php
Line 
1<?php
2/*
3  V4.93 10 Oct 2006  (c) 2000-2010 John Lim (jlim#natsoft.com). All rights reserved.
4  Released under both BSD license and Lesser GPL library license.
5  Whenever there is any discrepancy between the two licenses,
6  the BSD license will take precedence.
7      Set tabs to 4 for best viewing.
8 
9  Latest version of ADODB is available at http://php.weblogs.com/adodb
10  ======================================================================
11 
12 This file provides PHP4 session management using the ADODB database
13 wrapper library, using Oracle CLOB's to store data. Contributed by achim.gosse@ddd.de.
14
15 Example
16 =======
17 
18    include('adodb.inc.php');
19    include('adodb-session.php');
20    session_start();
21    session_register('AVAR');
22    $_SESSION['AVAR'] += 1;
23    print "
24-- \$_SESSION['AVAR']={$_SESSION['AVAR']}</p>";
25   
26To force non-persistent connections, call adodb_session_open first before session_start():
27
28    include('adodb.inc.php');
29    include('adodb-session.php');
30    adodb_session_open(false,false,false);
31    session_start();
32    session_register('AVAR');
33    $_SESSION['AVAR'] += 1;
34    print "
35-- \$_SESSION['AVAR']={$_SESSION['AVAR']}</p>";
36
37 
38 Installation
39 ============
40 1. Create this table in your database (syntax might vary depending on your db):
41 
42  create table sessions (
43       SESSKEY char(32) not null,
44       EXPIRY int(11) unsigned not null,
45       EXPIREREF varchar(64),
46       DATA CLOB,
47      primary key (sesskey)
48  );
49
50
51  2. Then define the following parameters in this file:
52    $ADODB_SESSION_DRIVER='database driver, eg. mysql or ibase';
53    $ADODB_SESSION_CONNECT='server to connect to';
54    $ADODB_SESSION_USER ='user';
55    $ADODB_SESSION_PWD ='password';
56    $ADODB_SESSION_DB ='database';
57    $ADODB_SESSION_TBL = 'sessions'
58    $ADODB_SESSION_USE_LOBS = false; (or, if you wanna use CLOBS (= 'CLOB') or ( = 'BLOB')
59   
60  3. Recommended is PHP 4.1.0 or later. There are documented
61     session bugs in earlier versions of PHP.
62
63  4. If you want to receive notifications when a session expires, then
64     you can tag a session with an EXPIREREF, and before the session
65     record is deleted, we can call a function that will pass the EXPIREREF
66     as the first parameter, and the session key as the second parameter.
67     
68     To do this, define a notification function, say NotifyFn:
69     
70        function NotifyFn($expireref, $sesskey)
71        {
72        }
73     
74     Then you need to define a global variable $ADODB_SESSION_EXPIRE_NOTIFY.
75     This is an array with 2 elements, the first being the name of the variable
76     you would like to store in the EXPIREREF field, and the 2nd is the
77     notification function's name.
78     
79     In this example, we want to be notified when a user's session
80     has expired, so we store the user id in the global variable $USERID,
81     store this value in the EXPIREREF field:
82     
83        $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn');
84       
85    Then when the NotifyFn is called, we are passed the $USERID as the first
86    parameter, eg. NotifyFn($userid, $sesskey).
87*/
88
89if (!defined('_ADODB_LAYER')) {
90    include (dirname(__FILE__).'/adodb.inc.php');
91}
92
93if (!defined('ADODB_SESSION')) {
94
95 define('ADODB_SESSION',1);
96 
97 /* if database time and system time is difference is greater than this, then give warning */
98 define('ADODB_SESSION_SYNCH_SECS',60);
99
100/****************************************************************************************\
101    Global definitions
102\****************************************************************************************/
103GLOBAL  $ADODB_SESSION_CONNECT,
104    $ADODB_SESSION_DRIVER,
105    $ADODB_SESSION_USER,
106    $ADODB_SESSION_PWD,
107    $ADODB_SESSION_DB,
108    $ADODB_SESS_CONN,
109    $ADODB_SESS_LIFE,
110    $ADODB_SESS_DEBUG,
111    $ADODB_SESSION_EXPIRE_NOTIFY,
112    $ADODB_SESSION_CRC,
113    $ADODB_SESSION_USE_LOBS,
114    $ADODB_SESSION_TBL;
115   
116    if (!isset($ADODB_SESSION_USE_LOBS)) $ADODB_SESSION_USE_LOBS = 'CLOB';
117   
118    $ADODB_SESS_LIFE = ini_get('session.gc_maxlifetime');
119    if ($ADODB_SESS_LIFE <= 1) {
120     // bug in PHP 4.0.3 pl 1  -- how about other versions?
121     //print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $ADODB_SESS_LIFE</h3>";
122        $ADODB_SESS_LIFE=1440;
123    }
124    $ADODB_SESSION_CRC = false;
125    //$ADODB_SESS_DEBUG = true;
126   
127    //////////////////////////////////
128    /* SET THE FOLLOWING PARAMETERS */
129    //////////////////////////////////
130   
131    if (empty($ADODB_SESSION_DRIVER)) {
132        $ADODB_SESSION_DRIVER='mysql';
133        $ADODB_SESSION_CONNECT='localhost';
134        $ADODB_SESSION_USER ='root';
135        $ADODB_SESSION_PWD ='';
136        $ADODB_SESSION_DB ='xphplens_2';
137    }
138   
139    if (empty($ADODB_SESSION_EXPIRE_NOTIFY)) {
140        $ADODB_SESSION_EXPIRE_NOTIFY = false;
141    }
142    //  Made table name configurable - by David Johnson djohnson@inpro.net
143    if (empty($ADODB_SESSION_TBL)){
144        $ADODB_SESSION_TBL = 'sessions';
145    }
146   
147
148    // defaulting $ADODB_SESSION_USE_LOBS
149    if (!isset($ADODB_SESSION_USE_LOBS) || empty($ADODB_SESSION_USE_LOBS)) {
150        $ADODB_SESSION_USE_LOBS = false;
151    }
152
153    /*
154    $ADODB_SESS['driver'] = $ADODB_SESSION_DRIVER;
155    $ADODB_SESS['connect'] = $ADODB_SESSION_CONNECT;
156    $ADODB_SESS['user'] = $ADODB_SESSION_USER;
157    $ADODB_SESS['pwd'] = $ADODB_SESSION_PWD;
158    $ADODB_SESS['db'] = $ADODB_SESSION_DB;
159    $ADODB_SESS['life'] = $ADODB_SESS_LIFE;
160    $ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
161   
162    $ADODB_SESS['debug'] = $ADODB_SESS_DEBUG;
163    $ADODB_SESS['table'] = $ADODB_SESS_TBL;
164    */
165   
166/****************************************************************************************\
167    Create the connection to the database.
168   
169    If $ADODB_SESS_CONN already exists, reuse that connection
170\****************************************************************************************/
171function adodb_sess_open($save_path, $session_name,$persist=true)
172{
173GLOBAL $ADODB_SESS_CONN;
174    if (isset($ADODB_SESS_CONN)) return true;
175   
176GLOBAL  $ADODB_SESSION_CONNECT,
177    $ADODB_SESSION_DRIVER,
178    $ADODB_SESSION_USER,
179    $ADODB_SESSION_PWD,
180    $ADODB_SESSION_DB,
181    $ADODB_SESS_DEBUG;
182   
183    // cannot use & below - do not know why...
184    $ADODB_SESS_CONN = ADONewConnection($ADODB_SESSION_DRIVER);
185    if (!empty($ADODB_SESS_DEBUG)) {
186        $ADODB_SESS_CONN->debug = true;
187        ADOConnection::outp( " conn=$ADODB_SESSION_CONNECT user=$ADODB_SESSION_USER pwd=$ADODB_SESSION_PWD db=$ADODB_SESSION_DB ");
188    }
189    if ($persist) $ok = $ADODB_SESS_CONN->PConnect($ADODB_SESSION_CONNECT,
190            $ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
191    else $ok = $ADODB_SESS_CONN->Connect($ADODB_SESSION_CONNECT,
192            $ADODB_SESSION_USER,$ADODB_SESSION_PWD,$ADODB_SESSION_DB);
193   
194    if (!$ok) ADOConnection::outp( "
195-- Session: connection failed</p>",false);
196}
197
198/****************************************************************************************\
199    Close the connection
200\****************************************************************************************/
201function adodb_sess_close()
202{
203global $ADODB_SESS_CONN;
204
205    if ($ADODB_SESS_CONN) $ADODB_SESS_CONN->Close();
206    return true;
207}
208
209/****************************************************************************************\
210    Slurp in the session variables and return the serialized string
211\****************************************************************************************/
212function adodb_sess_read($key)
213{
214global $ADODB_SESS_CONN,$ADODB_SESSION_TBL,$ADODB_SESSION_CRC;
215
216    $rs = $ADODB_SESS_CONN->Execute("SELECT data FROM $ADODB_SESSION_TBL WHERE sesskey = '$key' AND expiry >= " . time());
217    if ($rs) {
218        if ($rs->EOF) {
219            $v = '';
220        } else
221            $v = rawurldecode(reset($rs->fields));
222           
223        $rs->Close();
224       
225        // new optimization adodb 2.1
226        $ADODB_SESSION_CRC = strlen($v).crc32($v);
227       
228        return $v;
229    }
230   
231    return ''; // thx to Jorma Tuomainen, webmaster#wizactive.com
232}
233
234/****************************************************************************************\
235    Write the serialized data to a database.
236   
237    If the data has not been modified since adodb_sess_read(), we do not write.
238\****************************************************************************************/
239function adodb_sess_write($key, $val)
240{
241    global
242        $ADODB_SESS_CONN,
243        $ADODB_SESS_LIFE,
244        $ADODB_SESSION_TBL,
245        $ADODB_SESS_DEBUG,
246        $ADODB_SESSION_CRC,
247        $ADODB_SESSION_EXPIRE_NOTIFY,
248        $ADODB_SESSION_DRIVER,          // added
249        $ADODB_SESSION_USE_LOBS;        // added
250
251    $expiry = time() + $ADODB_SESS_LIFE;
252   
253    // crc32 optimization since adodb 2.1
254    // now we only update expiry date, thx to sebastian thom in adodb 2.32
255    if ($ADODB_SESSION_CRC !== false && $ADODB_SESSION_CRC == strlen($val).crc32($val)) {
256        if ($ADODB_SESS_DEBUG) echo "
257-- Session: Only updating date - crc32 not changed</p>";
258        $qry = "UPDATE $ADODB_SESSION_TBL SET expiry=$expiry WHERE sesskey='$key' AND expiry >= " . time();
259        $rs = $ADODB_SESS_CONN->Execute($qry); 
260        return true;
261    }
262    $val = rawurlencode($val);
263   
264    $arr = array('sesskey' => $key, 'expiry' => $expiry, 'data' => $val);
265    if ($ADODB_SESSION_EXPIRE_NOTIFY) {
266        $var = reset($ADODB_SESSION_EXPIRE_NOTIFY);
267        global $$var;
268        $arr['expireref'] = $$var;
269    }
270
271   
272    if ($ADODB_SESSION_USE_LOBS === false) {    // no lobs, simply use replace()
273        $rs = $ADODB_SESS_CONN->Replace($ADODB_SESSION_TBL,$arr, 'sesskey',$autoQuote = true);
274        if (!$rs) {
275            $err = $ADODB_SESS_CONN->ErrorMsg();
276        }
277    } else {
278        // what value shall we insert/update for lob row?
279        switch ($ADODB_SESSION_DRIVER) {
280            // empty_clob or empty_lob for oracle dbs
281            case "oracle":
282            case "oci8":
283            case "oci8po":
284            case "oci805":
285                $lob_value = sprintf("empty_%s()", strtolower($ADODB_SESSION_USE_LOBS));
286                break;
287
288            // null for all other
289            default:
290                $lob_value = "null";
291                break;
292        }
293
294        // do we insert or update? => as for sesskey
295        $res = $ADODB_SESS_CONN->Execute("select count(*) as cnt from $ADODB_SESSION_TBL where sesskey = '$key'");
296        if ($res && reset($res->fields) > 0) {
297            $qry = sprintf("update %s set expiry = %d, data = %s where sesskey = '%s'", $ADODB_SESSION_TBL, $expiry, $lob_value, $key);
298        } else {
299            // insert
300            $qry = sprintf("insert into %s (sesskey, expiry, data) values ('%s', %d, %s)", $ADODB_SESSION_TBL, $key, $expiry, $lob_value);
301        }
302
303        $err = "";
304        $rs1 = $ADODB_SESS_CONN->Execute($qry);
305        if (!$rs1) {
306            $err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
307        }
308        $rs2 = $ADODB_SESS_CONN->UpdateBlob($ADODB_SESSION_TBL, 'data', $val, "sesskey='$key'", strtoupper($ADODB_SESSION_USE_LOBS));
309        if (!$rs2) {
310            $err .= $ADODB_SESS_CONN->ErrorMsg()."\n";
311        }
312        $rs = ($rs1 && $rs2) ? true : false;
313    }
314
315    if (!$rs) {
316        ADOConnection::outp( '
317-- Session Replace: '.nl2br($err).'</p>',false);
318    }  else {
319        // bug in access driver (could be odbc?) means that info is not commited
320        // properly unless select statement executed in Win2000
321        if ($ADODB_SESS_CONN->databaseType == 'access')
322            $rs = $ADODB_SESS_CONN->Execute("select sesskey from $ADODB_SESSION_TBL WHERE sesskey='$key'");
323    }
324    return !empty($rs);
325}
326
327function adodb_sess_destroy($key)
328{
329    global $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
330   
331    if ($ADODB_SESSION_EXPIRE_NOTIFY) {
332        reset($ADODB_SESSION_EXPIRE_NOTIFY);
333        $fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
334        $savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
335        $rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
336        $ADODB_SESS_CONN->SetFetchMode($savem);
337        if ($rs) {
338            $ADODB_SESS_CONN->BeginTrans();
339            while (!$rs->EOF) {
340                $ref = $rs->fields[0];
341                $key = $rs->fields[1];
342                $fn($ref,$key);
343                $del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
344                $rs->MoveNext();
345            }
346            $ADODB_SESS_CONN->CommitTrans();
347        }
348    } else {
349        $qry = "DELETE FROM $ADODB_SESSION_TBL WHERE sesskey = '$key'";
350        $rs = $ADODB_SESS_CONN->Execute($qry);
351    }
352    return $rs ? true : false;
353}
354
355function adodb_sess_gc($maxlifetime)
356{
357    global $ADODB_SESS_DEBUG, $ADODB_SESS_CONN, $ADODB_SESSION_TBL,$ADODB_SESSION_EXPIRE_NOTIFY;
358   
359    if ($ADODB_SESSION_EXPIRE_NOTIFY) {
360        reset($ADODB_SESSION_EXPIRE_NOTIFY);
361        $fn = next($ADODB_SESSION_EXPIRE_NOTIFY);
362        $savem = $ADODB_SESS_CONN->SetFetchMode(ADODB_FETCH_NUM);
363        $t = time();
364        $rs = $ADODB_SESS_CONN->Execute("SELECT expireref,sesskey FROM $ADODB_SESSION_TBL WHERE expiry < $t");
365        $ADODB_SESS_CONN->SetFetchMode($savem);
366        if ($rs) {
367            $ADODB_SESS_CONN->BeginTrans();
368            while (!$rs->EOF) {
369                $ref = $rs->fields[0];
370                $key = $rs->fields[1];
371                $fn($ref,$key);
372                $del = $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE sesskey='$key'");
373                $rs->MoveNext();
374            }
375            $rs->Close();
376           
377            //$ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < $t");
378            $ADODB_SESS_CONN->CommitTrans();
379           
380        }
381    } else {
382        $ADODB_SESS_CONN->Execute("DELETE FROM $ADODB_SESSION_TBL WHERE expiry < " . time());
383   
384        if ($ADODB_SESS_DEBUG) ADOConnection::outp("
385-- <b>Garbage Collection</b>: $qry</p>");
386    }
387    // suggested by Cameron, "GaM3R" <gamr@outworld.cx>
388    if (defined('ADODB_SESSION_OPTIMIZE')) {
389    global $ADODB_SESSION_DRIVER;
390   
391        switch( $ADODB_SESSION_DRIVER ) {
392            case 'mysql':
393            case 'mysqlt':
394                $opt_qry = 'OPTIMIZE TABLE '.$ADODB_SESSION_TBL;
395                break;
396            case 'postgresql':
397            case 'postgresql7':
398                $opt_qry = 'VACUUM '.$ADODB_SESSION_TBL;   
399                break;
400        }
401        if (!empty($opt_qry)) {
402            $ADODB_SESS_CONN->Execute($opt_qry);
403        }
404    }
405    if ($ADODB_SESS_CONN->dataProvider === 'oci8') $sql = 'select  TO_CHAR('.($ADODB_SESS_CONN->sysTimeStamp).', \'RRRR-MM-DD HH24:MI:SS\') from '. $ADODB_SESSION_TBL;
406    else $sql = 'select '.$ADODB_SESS_CONN->sysTimeStamp.' from '. $ADODB_SESSION_TBL;
407   
408    $rs =& $ADODB_SESS_CONN->SelectLimit($sql,1);
409    if ($rs && !$rs->EOF) {
410   
411        $dbts = reset($rs->fields);
412        $rs->Close();
413        $dbt = $ADODB_SESS_CONN->UnixTimeStamp($dbts);
414        $t = time();
415        if (abs($dbt - $t) >= ADODB_SESSION_SYNCH_SECS) {
416            $msg =
417            __FILE__.": Server time for webserver {$_SERVER['HTTP_HOST']} not in synch with database: database=$dbt ($dbts), webserver=$t (diff=".(abs($dbt-$t)/3600)." hrs)";
418            error_log($msg);
419            if ($ADODB_SESS_DEBUG) ADOConnection::outp("
420-- $msg</p>");
421        }
422    }
423   
424    return true;
425}
426
427session_module_name('user');
428session_set_save_handler(
429    "adodb_sess_open",
430    "adodb_sess_close",
431    "adodb_sess_read",
432    "adodb_sess_write",
433    "adodb_sess_destroy",
434    "adodb_sess_gc");
435}
436
437/*  TEST SCRIPT -- UNCOMMENT */
438
439if (0) {
440
441    session_start();
442    session_register('AVAR');
443    $_SESSION['AVAR'] += 1;
444    ADOConnection::outp( "
445-- \$_SESSION['AVAR']={$_SESSION['AVAR']}</p>",false);
446}
447
448?>
Note: See TracBrowser for help on using the repository browser.