PHP会话没有写入数据库

时间:2015-03-05 10:44:40

标签: php session

我正在尝试使用session_set_save_handler将我的会话写入数据库,但我似乎无法使这些工作正常工作。

这是我的会话处理程序类:

<?php

require_once(__DIR__ .'/class.Database.php');

class MySessionHandler implements SessionHandlerInterface {

    var $db;

    var $maxlifetime;

    function open($save_path, $name) {

        $this->maxlifetime = get_cfg_var('session.gc.maxlifetime');

        $this->db = new Database();

        if(!$this->db) {

            return false;

        }

        return true;

    }

    function close() {

        return true;

    }

    function read($session_id) {

        $result = $this->db->select('*', 'sessions')
                            ->where(array('session_id' => array('=', $session_id)))
                            ->run();

        return (string)@$result[0]['sessions'];

    }


    function write($session_id, $session_data) {

        $check_exists = $this->db->select('*', 'sessions')
                                    ->where(array('session_id' => array('=', $session_id)))
                                    ->run();

        if($check_exists->num_rows >= 1) {

            $this->db->update('sessions')
                        ->set(array('session_id' => $session_id, 'session_data' => $session_data))
                        ->where(array('session_id' => array('=', $session_id)))
                        ->run();

        } else {

            $this->db->insert('sessions')
                        ->values(array('session_id' => $session_id, 'session_data' => $session_data))
                        ->run();

        }

        return true;

    }

    function destroy($session_id) {

        $this->db->delete('session')
                    ->where(array('session_id' => array('=', $session_id)))
                    ->run();

    }

    function gc($lifetime) {



    }

}

这是我的数据库类:

<?php

class Database {

    protected $host;
    protected $username;
    protected $password;
    protected $database;

    private $build = NULL;

    public function __construct() {

        global $config;

        $this->host = $config['db']['host'];
        $this->username = $config['db']['username'];
        $this->password = $config['db']['password'];
        $this->database = $config['db']['database'];

        $this->mysqli = new mysqli($this->host, $this->username, $this->password, $this->database);

    }

    public function select($columns = '*', $table) {

        $this->build = 'SELECT ';

        if(is_array($columns) == TRUE) {

            $this->build .= implode(',', $columns);

        } else {

            $this->build .= $columns;

        }

        $this->build .= ' FROM `'. $table .'`';

        return $this;

    }

    public function delete($table) {

        $this->build = 'DELETE FROM `'. $table .'`';

        return $this;

    }

    public function update($table) {

        $this->build = 'UPDATE `'. $table .'`';

        return $this;

    }

    public function insert($table) {

        $this->build = 'INSERT INTO `'. $table .'`';

        return $this;

    }

    public function values($data) {

        $dataKeys = array_keys($data);
        $dataValues = array_values($data);

        $this->build .= ' ('. implode(',', $dataKeys) .') VALUES (';

        $newValues = array();

        foreach($dataValues as $value) {

            $newValues[] = '\''. $value .'\'';

        }

        $this->build .= implode(',', $newValues) .')';

        return $this;

    }

    public function set($data) {

        $this->build .= ' SET ';

        $dataArray = array();

        foreach($data as $key => $value) {

            $dataArray[] = '`'. $key .'`=\''. $value .'\'';

        }

        $this->build .= implode(',', $dataArray);

        return $this;

    }

    public function where($data) {

        $this->build .= ' WHERE ';

        if(is_array($data) == TRUE) {

            $dataKeys = array_keys($data);
            $dataValues = array_values($data);

            $i = 0;

            foreach($dataValues as $value) {

                if(empty($value[2]) == FALSE) {

                    $this->build .= $value[2] .' `'. $dataKeys[$i] .'` '. $value[0] .' \''. $value[1] .'\' ';

                } else {

                    $this->build .= '`'. $dataKeys[$i] .'` '. $value[0] .' \''. $value[1] .'\' ';

                }

                ++$i;

            }

        } else {

            $this->build .= $data;

        }

        return $this;

    }

    public function orderBy($field, $dir) {

        $this->build .= ' ORDER BY `'. $field .'` '. strtoupper($dir);

        return $this;

    }

    public function limit($max, $min = '0') {

        $this->build .= ' LIMIT '. $min .', '. $max;

        return $this;

    }

    public function run() {

        $query = $this->mysqli->query($this->build);

        return $query;

    }

}

我在配置文件中调用两个,我在索引页面中调用它,如下所示:

<?php

session_start();

$config['db']['host'] = 'localhost';
$config['db']['username'] = 'root';
$config['db']['password'] = 'password';
$config['db']['database'] = 'pizza';

$config['salt'] = 'randomsalt';

$classes = array('Database', 'MySessionHandler');

foreach($classes as $class) {

    require_once(__DIR__ .'/class.'. $class .'.php');

}

$sessionHandler = new MySessionHandler();

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

register_shutdown_function('session_write_close');

但它不起作用。请问有人能协助我吗?

由于

1 个答案:

答案 0 :(得分:1)

根据session_set_save_handler() Manual我认为,问题正在发生,因为在设置自定义处理程序之前,您正在使用session_start()开始会话,因此更改不起作用。

在设置所有处理程序后启动会话尝试尝试。


好的,我已经测试了你提供的代码并发现了一些问题。

首先,如前所述,在设置所有处理程序后,您应该开始使用session_start()进行会话。

辅助,从数据库中获取会话数据时遇到错误。我在MySessionHandler的代码中做了一些更改,发现它在以下情况下运行良好:

function read($session_id) {

    $result = $this->db->select('*', 'sessions')
                        ->where(array('session_id' => array('=', $session_id)))
                        ->run();

    if(!$result) {
        // default value for empty session
        return [];
    } else {
        // fetching data record
        $record = $result->fetch_assoc()['session_data'];
    }
    // unserializing data record
    return unserialize($record);
}

function write($session_id, $session_data) {

    $check_exists = $this->db->select('*', 'sessions')
                                ->where(array('session_id' => array('=', $session_id)))
                                ->run();

    if($check_exists->num_rows >= 1) {
        // added serialization on save
        $this->db->update('sessions')
                    ->set(array('session_id' => $session_id, 'session_data' => serialize($session_data)))
                    ->where(array('session_id' => array('=', $session_id)))
                    ->run();

    } else {
        // added serialization on save
        $this->db->insert('sessions')
                    ->values(array('session_id' => $session_id, 'session_data' => serialize($session_data)))
                    ->run();

    }

    return true;

}

您可以选择序列化的方式,但是应该序列化,因为会话通常是$_SESSION变量上的数组。