Session Handling

目录

简介

SessionHandler is a special class that can be used to expose the current internal PHP session save handler by inheritance. There are seven methods which wrap the seven internal session save handler callbacks (open, close, read, write, destroy, gc and create_sid). By default, this class will wrap whatever internal save handler is set as defined by the session.save_handler configuration directive which is usually files by default. Other internal session save handlers are provided by PHP extensions such as SQLite (as sqlite), Memcache (as memcache), and Memcached (as memcached).

When a plain instance of SessionHandler is set as the save handler using session_set_save_handler it will wrap the current save handlers. A class extending from SessionHandler allows you to override the methods or intercept or filter them by calls the parent class methods which ultimately wrap the internal PHP session handlers.

This allows you, for example, to intercept the read and write methods to encrypt/decrypt the session data and then pass the result to and from the parent class. Alternatively one might chose to entirely override a method like the garbage collection callback gc.

Because the SessionHandler wraps the current internal save handler methods, the above example of encryption can be applied to any internal save handler without having to know the internals of the handlers.

To use this class, first set the save handler you wish to expose using session.save_handler and then pass an instance of SessionHandler or one extending it to session_set_save_handler.

Please note the callback methods of this class are designed to be called internally by PHP and are not meant to be called from user-space code. The return values are equally processed internally by PHP. For more information on the session workflow, please refer session_set_save_handler.

类摘要

SessionHandler

class SessionHandler implements SessionHandlerInterface , SessionIdInterface {

/* 方法 */

public bool close ( void )

public string create_sid ( void )

public bool destroy ( string $session_id )

public int gc ( int $maxlifetime )

public bool open ( string $save_path , string $session_name )

public string read ( string $session_id )

public bool write ( string $session_id , string $session_data )

}

Warning

This class is designed to expose the current internal PHP session save handler, if you want to write your own custom save handlers, please implement the SessionHandlerInterface interface instead of extending from SessionHandler.

更新日志

版本说明
5.5.1Added SessionHandler::create_sid.

示例 #1 Using SessionHandler to add encryption to internal PHP save handlers.

<?php

 /**
  * decrypt AES 256
  *
  * @param data $edata
  * @param string $password
  * @return decrypted data
  */
function decrypt($edata, $password) {
    $data = base64_decode($edata);
    $salt = substr($data, 0, 16);
    $ct = substr($data, 16);

    $rounds = 3; // depends on key length
    $data00 = $password.$salt;
    $hash = array();
    $hash[0] = hash('sha256', $data00, true);
    $result = $hash[0];
    for ($i = 1; $i < $rounds; $i++) {
        $hash[$i] = hash('sha256', $hash[$i - 1].$data00, true);
        $result .= $hash[$i];
    }
    $key = substr($result, 0, 32);
    $iv  = substr($result, 32,16);

    return openssl_decrypt($ct, 'AES-256-CBC', $key, true, $iv);
  }

/**
 * crypt AES 256
 *
 * @param data $data
 * @param string $password
 * @return base64 encrypted data
 */
function encrypt($data, $password) {
    // Set a random salt
    $salt = openssl_random_pseudo_bytes(16);

    $salted = '';
    $dx = '';
    // Salt the key(32) and iv(16) = 48
    while (strlen($salted) < 48) {
      $dx = hash('sha256', $dx.$password.$salt, true);
      $salted .= $dx;
    }

    $key = substr($salted, 0, 32);
    $iv  = substr($salted, 32,16);

    $encrypted_data = openssl_encrypt($data, 'AES-256-CBC', $key, true, $iv);
    return base64_encode($salt . $encrypted_data);
}

class EncryptedSessionHandler extends SessionHandler
{
    private $key;

    public function __construct($key)
    {
        $this->key = $key;
    }

    public function read($id)
    {
        $data = parent::read($id);

        if (!$data) {
            return "";
        } else {
            return decrypt($data, $this->key);
        }
    }

    public function write($id, $data)
    {
        $data = encrypt($data, $this->key);

        return parent::write($id, $data);
    }
}

// we'll intercept the native 'files' handler, but will equally work
// with other internal native handlers like 'sqlite', 'memcache' or 'memcached'
// which are provided by PHP extensions.
ini_set('session.save_handler', 'files');

$key = 'secret_string';
$handler = new EncryptedSessionHandler($key);
session_set_save_handler($handler, true);
session_start();

// proceed to set and retrieve values by key from $_SESSION

Note:

Since this class' methods are designed to be called internally by PHP as part of the normal session workflow, child class calls to parent methods (i.e. the actual internal native handlers) will return FALSE unless the session has actually been started (either automatically, or by explicit class="function">session_start. This is important to consider when writing unit tests where the class methods might be invoked manually.

SessionHandler::close

Close the session

说明

public bool SessionHandler::close ( void )

Closes the current session. This method is automatically executed internally by PHP when closing the session, or explicitly via session_write_close (which first calls the SessionHandler::write).

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was activated by session_set_save_handler.

If this class is extended by inheritiance, calling the parent close method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows the method to be overridden and or intercepted.

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::close.

参数

此函数没有参数。

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandler::create_sid

Return a new session ID

说明

public string SessionHandler::create_sid ( void )

Generates and returns a new session ID.

返回值

A session ID valid for the default session handler.

参见

  • session_id
  • session_create_id

SessionHandler::destroy

Destroy a session

说明

public bool SessionHandler::destroy ( string $session_id )

Destroys a session. Called internally by PHP with session_regenerate_id (assuming the $destroy is set to TRUE, by session_destroy or when session_decode fails.

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was set by session_set_save_handler.

If this class is extended by inheritiance, calling the parent destroy method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows this method to be overridden and or intercepted and filtered.

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::destroy.

参数

session_id
The session ID being destroyed.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandler::gc

Cleanup old sessions

说明

public int SessionHandler::gc ( int $maxlifetime )

Cleans up expired sessions. Called randomly by PHP internally when a session starts or when session_start is invoked. The frequency this is called is based on the session.gc_divisor and session.gc_probability configuration directives.

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was set by session_set_save_handler.

If this class is extended by inheritiance, calling the parent gc method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows this method to be overridden and or intercepted and filtered.

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::gc.

参数

maxlifetime
Sessions that have not updated for the last maxlifetime seconds will be removed.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandler::open

Initialize session

说明

public bool SessionHandler::open ( string $save_path , string $session_name )

Create new session, or re-initialize existing session. Called internally by PHP when a session starts either automatically or when session_start is invoked.

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was set by session_set_save_handler.

If this class is extended by inheritiance, calling the parent open method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows this method to be overridden and or intercepted and filtered.

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::open.

参数

save_path
The path where to store/retrieve the session.

session_name
The session name.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

参见

SessionHandler::read

Read session data

说明

public string SessionHandler::read ( string $session_id )

Reads the session data from the session storage, and returns the result back to PHP for internal processing. This method is called automatically by PHP when a session is started (either automatically or explicitly with session_start and is preceded by an internal call to the SessionHandler::open.

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was set by session_set_save_handler.

If this class is extended by inheritance, calling the parent read method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows the method to be overridden and or intercepted and filtered (for example, decrypting $data value returned by the parent read method).

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::read.

参数

session_id
The session id to read data for.

返回值

Returns an encoded string of the read data. If nothing was read, it must return an empty string. Note this value is returned internally to PHP for processing.

参见

SessionHandler::write

Write session data

说明

public bool SessionHandler::write ( string $session_id , string $session_data )

Writes the session data to the session storage. Called by normal PHP shutdown, by session_write_close, or when session_register_shutdown fails. PHP will call SessionHandler::close immediately after this method returns.

This method wraps the internal PHP save handler defined in the session.save_handler ini setting that was set before this handler was set by session_set_save_handler.

If this class is extended by inheritiance, calling the parent write method will invoke the wrapper for this method and therefore invoke the associated internal callback. This allows this method to be overridden and or intercepted and filtered (for example, encrypting the $data value before sending it to the parent write method).

For more information on what this method is expected to do, please refer to the documentation at SessionHandlerInterface::write.

参数

session_id
The session id.

session_data
The encoded session data. This data is the result of the PHP internally encoding the $_SESSION superglobal to a serialized string and passing it as this parameter. Please note sessions use an alternative serialization method.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

参见

简介

SessionHandlerInterface is an interface which defines a prototype for creating a custom session handler. In order to pass a custom session handler to session_set_save_handler using its OOP invocation, the class must implement this interface.

Please note the callback methods of this class are designed to be called internally by PHP and are not meant to be called from user-space code.

类摘要

SessionHandlerInterface

class SessionHandlerInterface {

/* 方法 */

abstract public bool close ( void )

abstract public bool destroy ( string $session_id )

abstract public int gc ( int $maxlifetime )

abstract public bool open ( string $save_path , string $session_name )

abstract public string read ( string $session_id )

abstract public bool write ( string $session_id , string $session_data )

}

示例 #1 Example using SessionHandlerInterface

The following example provides file based session storage similar to the PHP sessions default save handler files. This example could easily be extended to cover database storage using your favorite PHP supported database engine.

Note we use the OOP prototype with session_set_save_handler and register the shutdown function using the function's parameter flag. This is generally advised when registering objects as session save handlers.

Caution

For brevity, this example omits input validation. However, the $id parameters are actually user supplied values which require proper validation/sanitization to avoid vulnerabilities, such as path traversal issues. So do not use this example unmodified in production environments.

<?php
class MySessionHandler implements SessionHandlerInterface
{
    private $savePath;

    public function open($savePath, $sessionName)
    {
        $this->savePath = $savePath;
        if (!is_dir($this->savePath)) {
            mkdir($this->savePath, 0777);
        }

        return true;
    }

    public function close()
    {
        return true;
    }

    public function read($id)
    {
        return (string)@file_get_contents("$this->savePath/sess_$id");
    }

    public function write($id, $data)
    {
        return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
    }

    public function destroy($id)
    {
        $file = "$this->savePath/sess_$id";
        if (file_exists($file)) {
            unlink($file);
        }

        return true;
    }

    public function gc($maxlifetime)
    {
        foreach (glob("$this->savePath/sess_*") as $file) {
            if (filemtime($file) + $maxlifetime < time() && file_exists($file)) {
                unlink($file);
            }
        }

        return true;
    }
}

$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();

// proceed to set and retrieve values by key from $_SESSION

SessionHandlerInterface::close

Close the session

说明

abstract public bool SessionHandlerInterface::close ( void )

Closes the current session. This function is automatically executed when closing the session, or explicitly via session_write_close.

参数

此函数没有参数。

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandlerInterface::destroy

Destroy a session

说明

abstract public bool SessionHandlerInterface::destroy ( string $session_id )

Destroys a session. Called by session_regenerate_id (with $destroy = TRUE), session_destroy and when session_decode fails.

参数

session_id
The session ID being destroyed.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandlerInterface::gc

Cleanup old sessions

说明

abstract public int SessionHandlerInterface::gc ( int $maxlifetime )

Cleans up expired sessions. Called by session_start, based on session.gc_divisor, session.gc_probability and session.gc_maxlifetime settings.

参数

maxlifetime
Sessions that have not updated for the last maxlifetime seconds will be removed.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

SessionHandlerInterface::open

Initialize session

说明

abstract public bool SessionHandlerInterface::open ( string $save_path , string $session_name )

Re-initialize existing session, or creates a new one. Called when a session starts or when session_start is invoked.

参数

save_path
The path where to store/retrieve the session.

session_name
The session name.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

参见

SessionHandlerInterface::read

Read session data

说明

abstract public string SessionHandlerInterface::read ( string $session_id )

Reads the session data from the session storage, and returns the results. Called right after the session starts or when session_start is called. Please note that before this method is called SessionHandlerInterface::open is invoked.

This method is called by PHP itself when the session is started. This method should retrieve the session data from storage by the session ID provided. The string returned by this method must be in the same serialized format as when originally passed to the SessionHandlerInterface::write If the record was not found, return an empty string.

The data returned by this method will be decoded internally by PHP using the unserialization method specified in session.serialize_handler. The resulting data will be used to populate the $_SESSION superglobal.

Note that the serialization scheme is not the same as unserialize and can be accessed by session_decode.

参数

session_id
The session id.

返回值

Returns an encoded string of the read data. If nothing was read, it must return an empty string. Note this value is returned internally to PHP for processing.

参见

SessionHandlerInterface::write

Write session data

说明

abstract public bool SessionHandlerInterface::write ( string $session_id , string $session_data )

Writes the session data to the session storage. Called by session_write_close, when session_register_shutdown fails, or during a normal shutdown. Note: SessionHandlerInterface::close is called immediately after this function.

PHP will call this method when the session is ready to be saved and closed. It encodes the session data from the $_SESSION superglobal to a serialized string and passes this along with the session ID to this method for storage. The serialization method used is specified in the session.serialize_handler setting.

Note this method is normally called by PHP after the output buffers have been closed unless explicitly called by session_write_close

参数

session_id
The session id.

session_data
The encoded session data. This data is the result of the PHP internally encoding the $_SESSION superglobal to a serialized string and passing it as this parameter. Please note sessions use an alternative serialization method.

返回值

会话存储的返回值(通常成功返回 0,失败返回 1)。

参见