session_set_save_handler gc($ maxlifetime)工作理念

时间:2016-04-01 12:00:45

标签: php mysql session garbage-collection session-set-save-handler

php.net手册' s session_set_save_handler示例是基于文件的。我试图为mysql实现它。

我在Windows中使用 uniserver 。我的错误显示设置是开发环境。

我的问题是我无法自动完成垃圾收集功能。我没有错误/警告。我所有相关的代码都在下面。

我的意思是:如果我在会话测试后在index.php中使用$handler->gc($maxlifetime);,它会工作并删除过期的行。

如果我不在index.php中使用$handler->gc($maxlifetime);,则会保留过期的行。

我的问题

q1 - 我应该在index.php中使用$handler->gc($maxlifetime);吗?

q2 - 如果回答q1为YES,为什么回调函数具有gc功能。

q3 - 如果对q1的答案为否,那么为什么我的过期行不会被删除(如果我在index.php中没有$handler->gc($maxlifetime);)我关闭后浏览器(ie11),刷新index.php并检查我的mysql会话表?请注意$maxlifetime是1(秒)。

谢谢,最好的问候

my index.php

// populate inclusion paths
...

// mysql PDO connect
require_once("config.php");
$dbh = new PDO("mysql:host=$my_host;dbname=$my_db;charset=utf8", $my_username, $my_password);

// start session
require_once("class_Session.php");

$maxlifetime = 1; // seconds

$handler = new MySessionHandler($dbh, $maxlifetime);

session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);

// the following prevents unexpected effects when using objects as save handlers
register_shutdown_function('session_write_close');

session_start();

$_SESSION['user'] = 'joe';

if (isset($_SESSION['user'])) { echo $_SESSION['user']; }

// note if I try code below, expired rows are deleted
// $handler->gc($maxlifetime);

// some other irrelevant-to-this case codes
...

// close mysql connection
$dbh = NULL;

MySessionHandler类

class MySessionHandler {

    private $_db;
    private $maxlifetime;

    function __construct(PDO $dbh, $maxlifetime) 
    {
        $this->_db = $dbh;
        $this->maxlifetime = $maxlifetime;
        return (TRUE);
    }

    function open()
    {       

    }

    function close()
    {
        $this->_db = NULL;

        return (TRUE);
    }

    function read($id)
    {
        $query = "SELECT `data` FROM `sessions` WHERE id = ? LIMIT 1";
        $this->read_stmt = $this->_db->prepare($query);
        $this->read_stmt->bindParam(1, $id, PDO::PARAM_STR);
        $this->read_stmt->execute();
        $data = $this->read_stmt->fetchColumn();
        return $data;
    }

    function write($id, $data)
    {
        $query = "REPLACE `sessions` (`id`, `data`) VALUES(?,?)";
        $this->w_stmt = $this->_db->prepare($query);
        $this->w_stmt->bindParam(1, $id, PDO::PARAM_STR);
        $this->w_stmt->bindParam(2, $data, PDO::PARAM_STR);
        $this->w_stmt->execute();

        return (TRUE);
    }

    function destroy($id)
    {
        $query = "DELETE FROM `sessions` WHERE id = ?";
        $this->delete_stmt = $this->_db->prepare($query);
        $this->delete_stmt->bindParam(1, $id, PDO::PARAM_STR);
        $this->delete_stmt->execute();

        return (TRUE);
    }

    function gc($maxlifetime)
    {
        // instead of CURRENT_TIMESTAMP(), I also tried NOW() command
        $query = "DELETE FROM `sessions` WHERE `update_time` < CURRENT_TIMESTAMP() - INTERVAL ? SECOND";
        $this->gc_stmt = $this->_db->prepare($query);
        $this->gc_stmt->bindParam(1, $this->maxlifetime, PDO::PARAM_STR);
        $this->gc_stmt->execute();
        return (TRUE);

    }
}

会话表的相关SQL

CREATE TABLE `sessions`
(
    `id` CHAR(32) NOT NULL,
    `data` BLOB,
    `update_time` TIMESTAMP NOT NULL,
    PRIMARY KEY (id),
    INDEX (update_time)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_unicode_ci;

0 个答案:

没有答案