为什么会话ID经常变化?

时间:2017-04-03 10:00:14

标签: php database session session-cookies session-storage

我在数据库中设置了会话存储空间。当我调用session_destroy时,它会搜索数据库中的特定session_id以将其删除。

由于会话ID经常更改,新的session_id与之前存储的db session_id不匹配,因此这些会话数据不会被删除。即使是gc也无法正常工作。所有会话数据都将保存到数据库中,但不会被销毁。

DbSessionHandler.php

class DbSessionHandler implements SessionHandlerInterface{

public $dbconnect;
public function __construct($db){
    $this->dbconnect=$db;
    session_set_save_handler(
        array($this, 'open'),
        array($this, 'close'),
        array($this, 'read'),
        array($this, 'write'),
        array($this, 'destroy'),
        array($this, 'gc')
    );
    register_shutdown_function(session_write_close());
    session_start();
}

//make sure whether db connection is successfull
public function open($savepath, $id)
{
    return $this->dbconnect ? true : false;
}

public function close()
{
    return true;
}

//read from database based on id, always return a string even if it is empty
public function read($id)
{
    $data = "";   //declare empty string, if no data found, can return this empty string
    $session_row = $this->dbconnect->prepare("select session_data from session_store where session_id=:id");
    $session_row->execute(array(":id" => $id));
    if ($session_row->rowCount() > 0) {
        $datas = $session_row->fetch();
        $data=$datas["session_data"];
    }
    return $data;

}

/**
 * Write session_data using replace query (which does either insert or update)
 */
public function write($id, $data)
{
    if(!(empty($data))) {
        $time = time();
        $session_write = $this->dbconnect->prepare("REPLACE INTO session_store VALUES(:id,:data,:expire)");
        if ($session_write->execute(array(":id" => $id, ":data" => $data, ":expire" => $time))) {
            return true;
        }
    }
    return false;
}

/**
 * Destroy
 */
public function destroy($id)
{
    $destroy = $this->dbconnect->prepare("delete from session_store where session_id = :id");
    if ($destroy->execute(array(":id" => $id))) {
        return true;
    }
    return false;
}

/**
 * Garbage Collection
 */
public function gc($max)
{
    //Delete all records who have passed the expiration time
    $time=time();
    $delete = $this->dbconnect->prepare("delete from session_store where session_expire < :oldtime");
    if ($delete->execute(array(":oldtime" => $time - $max))) {
        return true;
    }
    return false;
}

}

启动会话的php文件:

function initiate_session()
{
$session_hash = 'sha512';
$session_name = 'some_name';
$secure = false;
$httponly = true;
ini_set('session.use_only_cookies', 1);
ini_set('session.hash_function', $session_hash);
ini_set('session.hash_bits_per_character', 5);
$cookieParams = session_get_cookie_params();
session_set_cookie_params($cookieParams['lifetime'], $cookieParams['path'], $cookieParams['domain'], $secure, $httponly);
session_name($session_name);
new DbSessionHandler(db_connect());

}

session_id

在此图像中,您可以看到,表中的session_id和脚本中的session_id是不同的,这使得数据库中的会话数据不会被删除。

1 个答案:

答案 0 :(得分:-1)

尝试使用它 session_regenerate_id(真);

传递TRUE布尔值将破坏旧会话ID,同时创建另一个。 你可以将它添加到initiate_session()函数。