Приглашаем посетить
Цветаева (tsvetaeva.lit-info.ru)

Implementing a Custom Session Management

Previous
Table of Contents
Next

Implementing a Custom Session Management

session_set_save_handler(
  'sess_open', 'sess_close', 'sess_read',
  'sess_write', 'sess_destroy', 'sess_gc');


There are some good reasons not to store session data in files. Performance might be one issue, with security as another issue. An alternative way to store session information is to use databases. For this, you just need a database table called sessiondata with three columns (the names might vary, but they have to be used in the upcoming listings):

  • Column id (primary key) is of type VARCHAR(32) and contains the session ID.

  • Column data is of type TEXT and contains the session data.

  • Column access is of type VARCHAR(14) and contains the time stamp of the most recent access to the session information.

It doesn't matter which database is used. This phrase uses MySQL and PHP5's new mysqli extension; however, it is trivial to change the code to work with other databases, as well (see Chapter 7, "Making Data Dynamic," for information about using many relevant databases with PHP).

The PHP function session_set_save_handler() can be used to provide custom functions for all relevant six session operations PHP uses internally:

  • Opening a session

  • Closing a session

  • Reading a session variable

  • Writing a session variable

  • Destroying a session

  • Cleaning up (garbage collection, for example removing old session data from the data store)

For all these six operations, the following listing contains code that reads and writes session data from and to a MySQL data source. You just need PHP 5 and have to set the connection parameters (server, username, password) appropriately. Then, you include the code from this listing using require_once and then use sessions as usual. In the background, PHP then saves all session information in the database and not in the file system.

<?php
  $GLOBALS['sess_server'] = 'localhost';
  $GLOBALS['sess_db'] = 'sessions';
  $GLOBALS['sess_username'] = 'user';
  $GLOBALS['sess_password'] = 'pass';

  function sess_open() {
    $GLOBALS['sess_mysqli'] = mysqli_connect(
      $GLOBALS['sess_server'],
      $GLOBALS['sess_username'],
      $GLOBALS['sess_password']
    );
    mysqli_select_db($GLOBALS['sess_mysqli'],
$GLOBALS['sess_db']);
  }

  function sess_close() {
    mysqli_close($GLOBALS['sess_mysqli']);
  }

  function sess_read($id) {
    $result = mysqli_query(
      $GLOBALS['sess_mysqli'],
      sprintf('SELECT data FROM sessiondata WHERE
         id = \'%s\'',

mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $id))
    );
    if ($row = mysqli_fetch_object($result)) {
      $ret = $row->data;
      mysqli_query(
        $GLOBALS['sess_mysqli'],
        sprintf('UPDATE sessiondata SET access=\
          '%s\' WHERE id=\'\'',
          date('YmdHis'),

mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $id))
      );
    } else {
      $ret = '';
    }
    return $ret;
  }

  function sess_write($id, $data) {
    mysqli_query(
      $GLOBALS['sess_mysqli'],
      sprintf('UPDATE sessiondata SET data=\'%s\',
        access=\'%s\' WHERE id=\'%s\'',
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $data),
        date('YmdHis'),
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $id))
    );
    if (mysqli_affected_rows($GLOBALS
             ['sess_mysqli']) < 1) {
      mysqli_query(
        $GLOBALS['sess_mysqli'],
        sprintf('INSERT INTO sessiondata (data,
          access, id) VALUES (\'%s\', \'%s\',
          \'%s\')',
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $data),
          date('YmdHis'),
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $id))
      );
    }
    return true;
  }
  function sess_destroy($id) {
    mysqli_query(
      $GLOBALS['sess_mysqli'],
      sprintf('DELETE FROM sessiondata WHERE
        id=\'%s\'',
mysqli_real_escape_string($GLOBALS['sess_mysqli'],
  $id))
    );
    return true;
  }

  function sess_gc($timeout) {
    $timestamp = date('YmdHis', time() - $timeout);
    mysqli_query(
      $GLOBALS['sess_mysqli'],
      sprintf('DELETE FROM sessiondata WHERE access
        < \'%s\'',
        $timestamp)
    );
  }

  session_set_save_handler(
    'sess_open', 'sess_close', 'sess_read',
    'sess_write', 'sess_destroy', 'sess_gc');
?>

TIP

The file session.sql in the download archive contains an SQL file to create the database table in MySQL. The file session_mysqli_readwrite.php uses the code in the preceding listing and saves some data in the session.


Figure 5.8 shows the contents in the session table after data has been written into it.

Figure 5.8. The session data now resides in the database.

Implementing a Custom Session Management



Previous
Table of Contents
Next