====== Session Management ====== [[v5:session:Index]]\\ [[v5:session:reference:index|Session Command Reference]]\\ ===== Introduction ===== ADOdb session management extends the standard functionality of PHP sessions, by allowing the normal session data seen to be stored in a database itself. There are numerous ways that this method enhances the default behavior * Simplified clean-up at end of session life * Easy analysis of session data * Simple session termination * **//Session data can be manipulated by external programs//** * Encryption of session data * Allows implementation of session termination callbacks * Session data can be retained if used across with load balancing servers ADOdb session management can be considered an extension of the normal behavior. It uses the same command syntax and structure as normal sessions, and honors the values defined in php.ini for sessions. These records will be garbage collected based on the php.ini [session] timeout settings. You can register a notification function to notify you when the record has expired and is about to be freed by the garbage collector. An alternative to using a database backed session handler is to use [[v5:userguide:memcached]]. This is a distributed memory based caching system suitable for storing session information. The original session management routines that use ''adodb-session.inc.php'' are deprecated as of ADOdb version 5.20, and will be removed in ADOdb Version 6.0.0. For information on upgrading from the original version, see [[v5:session:version1|Here]] ===== Driver Support ===== The following drivers are known to work with the adodb-session2.php file: - mysqli - pdo_mysqli (From ADOdb version 5.21) - postgres - oci8 This is not an exhaustive list, if you are using the system with a different database, let us know so we can add it to the list. ===== Usage ===== include_once "adodb/session/adodb-session2.php"; ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false); session_start(); /* * Test session vars, the following should increment on refresh */ if (!isset($_SESSION['AVAR'])) $_SESSION['AVAR'] = 0; $_SESSION['AVAR'] += 1; print "

\$_SESSION['AVAR']={$_SESSION['AVAR']}

";
When the session is created in session_start( ), the global variable ''$ADODB_SESS_CONN'' holds the connection object. The default name of the table is **sessions2**. ==== Overriding Table Name Defaults ==== include_once "adodb/session/adodb-session2.php"; $options['table'] = 'mytablename'; ADOdb_Session::config($driver, $host, $user, $password, $database,$options); session_start(); ===== ADOdb Session Handler Features ===== * Ability to define a notification function that is called when a session expires. Typically used to detect session logout and release global resources. * Optimization of database writes. We crc32 the session data and only perform an update to the session data if there is a data change. * Support for large amounts of session data with CLOBs (see adodb-session-clob2.php). Useful for Oracle. * Support for encrypted session data, see adodb-cryptsession2.php. Enabling encryption is simply a matter of including adodb-cryptsession2.php instead of adodb-session2.php. ==== Session Handler Files ==== There are 3 session management files that you can use: adodb-session2.php : The default adodb-cryptsession2.php : Use this if you want to store encrypted session data in the database adodb-session-clob2.php : Use this if you are storing DATA in clobs and you are NOT using oci8 driver ==== Non-persistent Connections==== To force non-persistent connections, call ''persist()'' before ''session_start()'': include_once "adodb/session/adodb-session2.php"; $driver = 'mysql'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; ADOdb_Session::config($driver, $host, $user, $password, $database, $options=false); ADOdb_Session::persist(false); session_start(); ==== DSN Support ==== using DSN support so you can set other options such as port number: include_once "adodb/session/adodb-session2.php"; $dsn = 'mysql://root:pwd@localhost/mydb?persist=1&port=5654'; ADOdb_Session::config($dsn, '', '', ''); session_start(); ===== Using Encrypted Sessions ===== To use encrypted sessions, replace the file ''adodb-session2.php'' with ''adodb-cryptsession2.php'': include 'adodb/session/adodb-cryptsession2.php'; $driver = 'mysql'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false); session_start(); And the same technique for adodb-session-clob2.php: include 'adodb/session/adodb-session2-clob2.php'; $driver = 'oci8'; $host = 'localhost'; $user = 'auser'; $pwd = 'secret'; $database = 'sessiondb'; ADOdb_Session::config($driver, $host, $user, $password, $database,$options=false); session_start(); ===== Installation ===== Create this table in your database. ==== MySQL or PDO MySQL ==== CREATE TABLE sessions2 ( sesskey VARCHAR( 64 ) COLLATE utf8mb4_bin NOT NULL DEFAULT '', expiry DATETIME NOT NULL , expireref VARCHAR( 250 ) DEFAULT '', created DATETIME NOT NULL , modified DATETIME NOT NULL , sessdata LONGTEXT, PRIMARY KEY ( sesskey ) , INDEX sess2_expiry( expiry ), INDEX sess2_expireref( expireref ) ) When [[https://www.php.net/manual/en/session.configuration.php#ini.session.sid-bits-per-character|session.sid_bits_per_character]] php.ini setting is set to 6, the //Session ID// can contain both upper and lowercase letters. Collisions could occur in this case, due to MySQL performing case-insensitive searches by default. To avoid that, the //sesskey// column should use binary (or a case-sensitive) collation. ==== PostgreSQL ==== CREATE TABLE sessions2( sesskey VARCHAR( 64 ) NOT NULL DEFAULT '', expiry TIMESTAMP NOT NULL , expireref VARCHAR( 250 ) DEFAULT '', created TIMESTAMP NOT NULL , modified TIMESTAMP NOT NULL , sessdata TEXT DEFAULT '', PRIMARY KEY ( sesskey ) ); create INDEX sess2_expiry on sessions2( expiry ); create INDEX sess2_expireref on sessions2 ( expireref ); ==== Oracle ==== This definition uses a CLOB for the SESSDATA field: CREATE TABLE SESSIONS2 ( SESSKEY VARCHAR2(48 BYTE) NOT NULL, EXPIRY DATE NOT NULL, EXPIREREF VARCHAR2(200 BYTE), CREATED DATE NOT NULL, MODIFIED DATE NOT NULL, SESSDATA CLOB, PRIMARY KEY(SESSKEY) ); CREATE INDEX SESS2_EXPIRY ON SESSIONS2(EXPIRY); CREATE INDEX SESS2_EXPIREREF ON SESSIONS2(EXPIREREF); We need to use a CLOB here because for text greater than 4000 bytes long, Oracle requires you to use the CLOB data type. If you are using the oci8 driver, ADOdb will automatically enable CLOB handling. So you can use either ''adodb-session2.php'' or ''adodb-session-clob2.php'' - in this case it doesn't matter. ===== Notifications ===== You can receive notification when your session is cleaned up by the session garbage collector or when you call //session_destroy()//. PHP's session extension will automatically run a special garbage collection function based on your php.ini session.cookie_lifetime and session.gc_probability settings. This will in turn call ADOdb's garbage collection function, which can be setup to perform notification. PHP Session --> ADOdb Session --> Find all recs --> Send --> Delete GC Function GC Function to be deleted notification queued executed at called by for all recs records random time Session queued for Extension deletion When a session is created, we need to store a value in the session record (in the EXPIREREF field), typically the userid of the session. Later when the session has expired, just before the record is deleted, we reload the EXPIREREF field and call the notification function with the value of EXPIREREF, which is the userid of the person being logged off. ADOdb uses a global variable $ADODB_SESSION_EXPIRE_NOTIFY that you must predefine before session start to store the notification configuration. $ADODB_SESSION_EXPIRE_NOTIFY is an array with 2 elements, the first being the name of the session variable you would like to store in the EXPIREREF field, and the 2nd is the notification function's name. For example, suppose we want to be notified when a user's session has expired, based on the userid. When the user logs in, we store the id in the global session variable $USERID. The function name is ''NotifyFn''. So we define (before session_start() is called): $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn'); And when the NotifyFn is called (when the session expires), the ''$EXPIREREF'' holding the user id is passed in as the first parameter, e.g. ''NotifyFn($userid, $sesskey)''. The session key (which is the primary key of the record in the sessions table) is the 2nd parameter. Here is an example of a Notification function that deletes some records in the database and temporary files: function NotifyFn($expireref, $sesskey) { global $ADODB_SESS_CONN; # the session connection object $user = $ADODB_SESS_CONN->qstr($expireref); $ADODB_SESS_CONN->execute("delete from shopping_cart where user=$user"); system("rm /work/tmpfiles/$expireref/*"); } EXPIREREF must be set manually, e.g. $GLOBALS['USERID'] = GetUserID(); $ADODB_SESSION_EXPIRE_NOTIFY = array('USERID','NotifyFn'); In older versions of ADOdb this could be achieved automatically through the use of register_globals, but this feature has been [[https://php-legacy-docs.zend.com/manual/php5/en/security.globals|removed in PHP 5.4 for security reasons]]. If you want to change the EXPIREREF after the session record has been created, you will need to modify any session variable to force a database record update. ===== Neat Notification Tricks ===== **ExpireRef** normally holds the user id of the current session. - You can then write a session monitor, scanning expireref to see who is currently logged on. - If you delete the sessions record for a specific user, eg. ''delete from sessions where expireref = '$USER''' then the user is logged out. Useful for ejecting someone from a site. - You can scan the sessions table to ensure no user can be logged in twice. Useful for security reasons. ===== Compression/Encryption Schemes ===== Multiple encryption and compression schemes are supported. Currently, supported are: * MD5Crypt (crypt.inc.php) * MCrypt * Secure (Horde's emulation of MCrypt, if MCrypt module is not available.) * GZip * BZip2 These are stackable. E.g. ADODB_Session::filter(new ADODB_Compress_Bzip2()); ADODB_Session::filter(new ADODB_Encrypt_MD5()); will compress and then encrypt the record in the database. ===== Backwards Compatibility ===== The older method of connecting to ADOdb using global variables is now deprecated, and **will be removed** in ADOdb version 6.0: $ADODB_SESSION_DRIVER='mysql'; $ADODB_SESSION_CONNECT='localhost'; $ADODB_SESSION_USER ='root'; $ADODB_SESSION_PWD ='abc'; $ADODB_SESSION_DB ='employees'; include 'adodb/adodb-session.php';