проблема обработчика сеанса базы данных - PullRequest
1 голос
/ 25 июля 2011

Здравствуйте, я пытаюсь понять, как работают сеансы и как работает session_set_handler(), поэтому я начал создавать класс для обработки сеансов, но у меня возникли некоторые проблемы с функцией write(). Можете ли вы помочь мне? решить проблему?

<?php
class Session extends Model
{
    public
        $connectionName = 'sessions',
        $sessionsId,
        $sessionsData;

    public function __construct()
    {
        parent::__construct();
        session_set_save_handler(
            array($this, 'Open'),
            array($this, 'Close'),
            array($this, 'Read'),
            array($this, 'Write'),
            array($this, 'Destroy'),
            array($this, 'Gc'));
        session_start();
    }

    public function __destruct()
    {
        session_write_close();
    }

    public function Open()
    {
        return true;
    }

    public function Close()
    {
        return true;
    }

    public function Read($sessionsId)
    {
        $this->stmt = $this->prepare("SELECT * FROM `sessions` WHERE `id` = :sessionId");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->execute();
        return $this->stmt->fetchAll();
    }

    public function Write($sessionsId, $sessionsData)
    {
        $this->stmt = $this->prepare("REPLACE INTO `sessions`.`sessions` 
        (`id`, `access`, `data`) 
        VALUES 
        (:sessionId, NOW(), :sessionValue)");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->bindParam(":sessionValue", $sessionsData);
        $this->stmt->execute();
    }

    public function Destroy($sessionsId)
    {
        $this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `id` = :sessionId");
        $this->stmt->bindParam(":sessionId", $sessionsId);
        $this->stmt->execute();
    }

    public function Gc()
    {
        $this->stmt = $this->prepare("DELETE FROM `sessions`.`sessions` WHERE `access` < NOW() - INTERVAL 1 HOUR");
        $this->stmt->execute();
    }
}

теперь приведенный выше код работает нормально, единственная проблема в том, что когда я пишу сеанс в db, я получаю следующую вставку:

дамп из mysql

CREATE TABLE IF NOT EXISTS `sessions` (
  `id` varchar(32) NOT NULL,
  `access` datetime NOT NULL,
  `data` text NOT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `sessions` (`id`, `access`, `data`) VALUES
('lhig71coed8ur81n85iiovje37', '2011-07-25 15:37:57', '');

Как видите, значение сеанса не вставлено, я получаю только идентификатор сеанса. на var_dump($sessionsData) я получаю:

"name|s:6:"Bogdan";"

и для var_dump($sessionsId) я получаю:

lhig71coed8ur81n85iiovje37

Не могли бы вы помочь? Я не получаю никаких проверенных ошибок. Сообщения об ошибках установки xampp logs сообщают обо всем, что я знал, даже в php.ini. Большое спасибо за то, что прочитали это и помогли мне.

1 Ответ

1 голос
/ 25 июля 2011

В вашей реализации обнаружен недостаток, который приводит к удалению любых данных сеанса:

return $this->stmt->fetchAll();

в

public function Read($sessionsId)

Эта функция должна возвращать строку, в вашем случае данные из поля data.

Но вы возвращаете массив (как это выглядит - не могу сказать конкретно, потому что фактическая база данных скрыта, PDO / MySQLi?).

Однако весьма вероятно, что десериализация данных сеанса (см. session_decode()) завершится неудачей, поэтому данные сеанса станут пустыми, а затем снова сохранятся (в виде пустой строки).

Это должно быть причиной вашей проблемы. Исправьте это, возвращая строковые данные из базы данных.


Кроме того, я подозреваю что-то вроде проблемы с кодировкой, но я не совсем уверен, что это вызывает это. Но просто учтите следующее:

Данные сеанса: двоичные данные, а не текст . Вы можете изменить определение таблицы и получить доступ соответственно. В MySQL для этого есть BLOB Тип , и bindParam() может помочь с PDO::PARAM_LOB спецификатором типа данных.

Вероятно, изменения такого типа помогут вам решить проблему. В противном случае это гарантирует, что вы сохраняете данные без изменений, что в любом случае вам и нужно. Придерживайтесь бинарно-безопасной обработки данных сеанса.

...