Я пытаюсь использовать 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');
Но это не сработает. Может ли кто-нибудь помочь мне в этом, пожалуйста?
благодаря
В соответствии с инструкцией session_set_save_handler(), я думаю, что эта проблема происходит, потому что вы начинаете сеанс с 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
.