描述
在PHP中可以通過定義session_set_save_handler,將服務器session數據存儲在不同的介質上,比如存儲在文件裡,apc或memcache緩存中,或存儲在數據庫裡。可對統計在線人數,或踢除特定會員的登陸狀態等等。
自定義session_set_save_handler,基本上就是使用自定義的讀寫方法覆蓋了系統默認的session的讀寫方法,以實現對session的管理。歡迎大家一起交流,有什麼疑問請寫信給我。
工廠類
[php]
<?php
/**
* CHttpSession
* http session 數據存儲引擎
*/
class CHttpSession {
private static $engine;
private static $gc_maxlifetime;
public static function engine( $enginer ) {
$enginer = ucfirst( $enginer );
$engineInstance = "CHttpSession{$enginer}";
$filename = SYS_MODULE . '/Session/' . $engineInstance . '.php';
if ( !file_exists( $filename )) {
throw new Exception( 'Fatal: not found {$filename} file' );
}
require( $filename );
if ( !class_exists( $engineInstance ) ) {
throw new Exception( 'Fatal: not found {$engineInstance} object' );
}
$handler = new CHttpSession( new $engineInstance );
ini_set( "session.save_handler", "user" );
ini_set( 'apc.ttl', 3600 );
ini_set( 'apc.user_ttl', 1200 );
ini_set( 'apc.gc_ttl', 3600 );
session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);
if ( isset( $_COOKIE['PHPSESSID'] ) ) {
session_start( $_COOKIE['PHPSESSID'] );
}
else {
session_start( );
setcookie( 'PHPSESSID', session_id(), null, '/', COOKIE_DOMAIN );
}
}
public function __construct( & $engine ) {
self::$engine = $engine;
self::$gc_maxlifetime = ini_get( 'session.gc_maxlifetime' );
}
public function read( $id ) {
return self::$engine->fetch( 'session/'.$id );
}
public function write ( $id , $data ) {
return self::$engine->add( 'session/'.$id, $data, self::$gc_maxlifetime );
}
public function close ( ) {
return true;
}
public function destroy ( $id ) {
return self::$engine->delete( 'session/'.$id );
}
public function __destruct ( ) {
session_write_close();
}
public function gc ( $maxlifetime ) {
return true;
}
public function open ( $save_path , $session_name ) {
return true;
}
};
具體方法
CHttpSessionFile
[php]
<?php
/**
* CFileHttpSession
* session引擎, 以文件的方式對session進行存儲, YPi框架默認session存儲引擎
* SESSION_DIR 設置session文件存儲路徑
*/
class CHttpSessionFile {
public function add( $key, $data, $cg_maxlifetime ) {
$filepath = substr( $key, 7 );
file_put_contents( SESSION_DIR.$filepath, $data );
return true;
}
public function fetch( $key ) {
$filepath = substr( $key, 7 );
if ( !file_exists(SESSION_DIR.$filepath) ) {
file_put_contents( SESSION_DIR.$filepath, '' );
return true;
}
return file_get_contents( SESSION_DIR.$filepath );
}
public function delete( $key ) {
$filepath = substr( $key, 7 );
if ( file_exists( SESSION_DIR.$filepath ) ) {
unlink( SESSION_DIR.$filepath );
}
return true;
}
};
CHttpSessionApc
[php]
<?php
/**
* CApcHttpSession
* session引擎, 以APC緩存的方式對session進行存儲
* SESSION_ENGINE 設置值為apc,以啟用APC方式對session進行存儲
*/
class CHttpSessionApc {
public function add( $key, $data, $cg_maxlifetime ) {
apc_store( $key, $data, $cg_maxlifetime );
return true;
}
public function fetch( $key ) {
if ( !apc_exists( $key ) ) {
apc_store( $key, '' );
return true;
}
return apc_fetch( $key );
}
public function delete( $key ) {
if ( apc_exists( $key ) ) {
apc_delete( $key );
}
return true;
}
};
CHttpSessionMemcache
[php]
<?php
/**
* CMemcacheHttpSession
* session引擎, 以memcache緩存的方式對session進行存儲 *
* SESSION_ENGINE 設置值為memcache,以啟用memcache方式對session進行存儲
* MEMCACHE_HOST 設置memcache服務器地址
* MEMCACHE_PORT 設置memcache服務器訪問端口號
*/
class CHttpSessionMemcache {
private static $memcache;
public function __constrct( $config ) {
self::$memcache = new Memcache;
self::$memcache->connect( MEMCACHE_HOST, MEMCACHE_PORT );
}
public function __destroy() {
self::$memcache->close();
}
public function add( $key, $data, $cg_maxlifetime ) {
return self::$memcache->add( $key, $data, $cg_maxlifetime );
}
public function fetch( $key ) {
return self::$memcache->get( $key );
}
public function delete( $key ) {
return self::$memcache->delete( $key );
}
};
實例說明
只需要把平時用的 session_start() 替換成以下的方法即可。
[php]
<?php
defined('SESSION_ENGINE')||define('SESSION_ENGINE', 'file');
require '../lib/CHttpSession.php';
CHttpSession::engine( SESSION_ENGINE );
摘自 yagas的專欄