PHP сессия не пишет в базу данных

0

Я пытаюсь использовать 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

1 ответ

1

В соответствии с инструкцией 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.

  • 0
    Только что попробовал, и он действительно записывает session_id в базу данных (но не session_data), а также ломает мою HTML-страницу?
  • 0
    Если это нарушает HTML, могут быть некоторые ошибки вывода. Проверьте ваш сгенерированный источник HTML.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню