php 深入理解session_set_save_handler执行机制

时间:2016-08-01
PHP可以使用session_set_save_handler()对Session 进行自定义处理,本文章通过实例向大家介绍session_set_save_handler处理执行机制,需要的朋友可以参考一下。

session handler默认启动顺序是session_start分别调用的回调函数。为open read ,然后等待脚本结束,收集$_SESSION(默认在内存中),然后关闭脚本,然后执行write,写入文件,然后close。

如何改变session handler默认启动顺序呢?

我们可以使用 session_commit(); 或者 session_write_close();函数调用的时候,session的机制就改变了,直接写入文件,关闭文件。然后再执行脚本。

下面来看一下PHP 使用 session_set_save_handler() 对 Session 进行自定义处理

/*
Session open (called by session_start( ))
Session close (called at page end)
Session read (called after session_start( ) )
Session write (called when session data is to be written)
Session destroy (called by session_destroy( ) )
Session garbage collect (called randomly)
*/
<?
    function sess_open($sess_path, $sess_name) {
            print "Session opened.\n";
            print "Sess_path: $sess_path\n";
            print "Sess_name: $sess_name\n\n";
            return true;
    }
 
    function sess_close( ) {
            print "Session closed.\n";
            return true;
    }
 
    function sess_read($sess_id) {
            print "Session read.\n";
            print "Sess_ID: $sess_id\n";
            return '';
    }
    /* http://www.manongjc.com/article/1293.html */
    function sess_write($sess_id, $data) {
            print "Session value written.\n";
            print "Sess_ID: $sess_id\n";
            print "Data: $data\n\n";
            return true;
    }
 
    function sess_destroy($sess_id) {
            print "Session destroy called.\n";
            return true;
    }
 
    function sess_gc($sess_maxlifetime) {
            print "Session garbage collection called.\n";
            print "Sess_maxlifetime: $sess_maxlifetime\n";
            return true;
    }
 
    session_set_save_handler("sess_open", "sess_close", "sess_read",
                    "sess_write", "sess_destroy", "sess_gc");
    session_start( );
 
    $_SESSION['foo'] = "bar";
    print "Some text\n";
    $_SESSION['baz'] = "wombat";
?>
1. 返回值的问题,为什么每个回调函数都有个retrun 的bool值?
2. 返回值的问题,比如read函数  返回一个false 会怎么样?true又怎么样?
3. 当session_start()开始后, 这个函数
session_set_save_handler('_session_open','_session_close','_session_read','_session_write','_session_destroy','_session_gc') 
里面的_session_read是不是就是session_id?

1. 返回值的问题,为什么每个回调函数都有个retrun 的bool值? Return Values Returns TRUE on success or FALSE on failure. 这个是函数的定义值。如果你不想用,可以不用catch他。 如果需要,这样写 A = session_set_save_handler() 返回值的问题,比如read函数 返回一个false 会怎么样?true又怎么样? 你可以结合IF来使用 比如 IF(session_set_save_handler()) 意思就是如果函数真.... session_set_save_handler('_session_open','_session_close','_session_read','_session_write','_session_destroy','_session_gc') 里面的_session_read是不是就是session_id? 是的,一个session就存一个系列的值 比如说你登陆一个网站,那你的所有动作产生的数据就在这个session里。



session_set_save_handler---设置用户级 session 存储函数

函数原型 

void session_set_save_handler (string open, string close, string read, string write, string destroy, string gc)

session_set_save_handler() 设置用户级 session 存储函数,用于存储和取回 session 相关的数据. 用于那些使用不同于 PHP Session 指定的存储方式的情况. 例如,在本地数据库存储 session 数据. 

注意: 你必须设置 php.ini 里面的 session.save_handler配置参数来让 session_set_save_handler() 正常工作. 

下面的例子提供了类似于 PHP 默认的保存文件句柄的基于文件的 session storage 方式. 这个例子可以很简单的扩展到使用熟悉的数据库引擎来进行数据库存储. 
例子:

程序代码:[session_inc.php]

<?php 
$SESS_DBHOST = "yourhost"; /* database server hostname */ 
$SESS_DBNAME = "yourdb"; /* database name */ 
$SESS_DBUSER = "youruser"; /* database user */ 
$SESS_DBPASS = "yourpassword"; /* database password */ 

$SESS_DBH = ""; 
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); 

function sess_open($save_path, $session_name) { 
    global $SESS_DBHOST, $SESS_DBNAME, $SESS_DBUSER, $SESS_DBPASS, $SESS_DBH; 

    if (! $SESS_DBH = mysql_pconnect($SESS_DBHOST, $SESS_DBUSER, $SESS_DBPASS)) { 
        echo "<li>Can't connect to $SESS_DBHOST as $SESS_DBUSER"; 
        echo "<li>MySQL Error: " . mysql_error(); 
        die; 
    } 

    if (! mysql_select_db($SESS_DBNAME, $SESS_DBH)) { 
        echo "<li>Unable to select database $SESS_DBNAME"; 
        die; 
    } 

    return true; 
} 

function sess_close() { 
    return true; 
} 

function sess_read($key) { 
    global $SESS_DBH, $SESS_LIFE; 

    $qry = "SELECT value FROM session_tbl WHERE sesskey = '$key' AND expiry > " . time(); 
    $qid = mysql_query($qry, $SESS_DBH); 

    if (list($value) = mysql_fetch_row($qid)) { 
        return $value; 
    } 

    return false; 
} 

function sess_write($key, $val) { 
    global $SESS_DBH, $SESS_LIFE; 

    $expiry = time() + $SESS_LIFE; //过期时间 
    $value = addslashes($val); 

    $qry = "INSERT INTO session_tbl VALUES ('$key', $expiry, '$value')"; 
    $qid = mysql_query($qry, $SESS_DBH); 

    if (! $qid) { 
        $qry = "UPDATE session_tbl SET expiry = $expiry, value = '$value' WHERE sesskey = '$key' AND expiry > " . time(); 
        $qid = mysql_query($qry, $SESS_DBH); 
    } 

    return $qid; 
} 

function sess_destroy($key) { 
    global $SESS_DBH; 

    $qry = "DELETE FROM session_tbl WHERE sesskey = '$key'"; 
    $qid = mysql_query($qry, $SESS_DBH); 

    return $qid; 
} 

function sess_gc($maxlifetime) { 
    global $SESS_DBH; 

    $qry = "DELETE FROM session_tbl WHERE expiry < " . time(); 
    $qid = mysql_query($qry, $SESS_DBH); 

    return mysql_affected_rows($SESS_DBH); 
} 

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

session_start(); 
?>

完成以上步骤后,在程序中使用require("session_inc.php")来代替session_start()即可,其他的session函数还是象以前一样的方法调用