Хранение сессий в PHP: не получается сериализовать переменные сессий - PullRequest
2 голосов
/ 06 января 2010

Я использую seralize и unseralize для установки и получения переменных сеанса из моей базы данных.

Пользователь находится в сеансе, и каждый раз, когда он нажимает сохранить. Я делаю это:

$array = serialize($_SESSION);
//and save to DB field

Когда пользователь загружает сеанс, я загружаю переменные, чтобы продолжить этот сеанс следующим образом:

//get row from DB
$_SESSION = unserialize($row['session_variables']);
  1. Это не работает для меня. Во-первых, он не десерализуется, так как возвращает что-то вроде этого, когда я print_r($_SESSION):

    Array (
        [user_id] => test2
        [date_created] =>
        [date_updated] =>
        [session_variables] => a:9:{s:7:"user_id";s:5:"test2";s:12:"date_created";N;s:12:"date_updated";N;s:17:"session_variables";s:149:"a:6:{s:7:"user_id";s:5:"test2";s:4:"here";s:2:"12";s:5:"here2";s:6:"112432";s:5:"here3";s:6:"132432";s:5:"here4";s:4:"1qw2";s:5:"here5";s:5:"1wqe2";}";s:4:"here";s:2:"12";s:5:"here2";s:6:"112432";s:5:"here3";s:6:"132432";s:5:"here4";s:4:"1qw2";s:5:"here5";s:5:"1wqe2";}
        [here] => 12
        [here2] => 112432
        [here3] => 132432
        [here4] => 1qw2
        [here5] => 1wqe2
    )
    
  2. Где session_id для этих переменных будет использоваться на разных страницах? Я переписал их?

Спасибо всем за помощь

EDIT

Сохраняется ли session_id в глобальном $ _SESSION? Я думаю, нет. Если я сбросил $ _SESSION, это означает, что сессия не пропадет, только переменные, правильно? Кто-нибудь подтвердит, пожалуйста?

Ответы [ 7 ]

7 голосов
/ 06 января 2010

Попробуйте это.

$array = base64_encode(serialize($_SESSION)); // going to the database
$_SESSION = unserialize(base64_decode($row['session_vars'])); // coming from the database

Часто MySQL не будет хорошо работать с сериализованными данными, если вы не base64_encode их. Посмотрите, поможет ли это.

2 голосов
/ 06 января 2010

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

Вместо этого создайте новый обработчик сеанса, который будет выполнять работу базы данных за вас. Сериализация / десериализация также обрабатывается для вас - вам не нужно явно вызывать эти функции. Кроме того, не используя установленный механизм для этого процесса, вы упускаете некоторые функциональные возможности (такие как сборщик мусора сеанса)

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

CREATE  TABLE IF NOT EXISTS `user_session` (
  `user_session_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `sess_id` VARCHAR(64) NOT NULL ,
  `sess_data` TEXT NOT NULL ,
  `sess_time` INT UNSIGNED NOT NULL ,
  PRIMARY KEY (`user_session_id`) ,
  INDEX `idx_sess_id` (`sess_id` ASC) ,
  INDEX `idx_sess_time` (`sess_time` ASC) )
ENGINE = InnoDB;

Далее следует создать класс с нужными нам методами. Я не собираюсь заполнять их все - это упражнение для вас;)

class MysqlSessionHandler
{
  protected $db;

  public function __construct( $db )
  {
    $this->db = $db
  }

  public function open()
  {

  } 

  public function close()
  {

  }

  public function read()
  {

  }

  public function write()
  {

  }

  public function destroy()
  {

  }

  public function gc()
  {

  }

  public function register()
  {
    return session_set_save_handler(
        array( $this, 'open' )
      , array( $this, 'close' )
      , array( $this, 'read' )
      , array( $this, 'write' )
      , array( $this, 'destroy' )
      , array( $this, 'gc' )
    );
  }
}

И основное использование будет

$sessionHandler = new MysqlSessionHandler( $db );
$sessionHandler->register();

И, наконец, вы всегда можете получить идентификатор текущей сессии, просто вызвав session_id ()

0 голосов
/ 10 марта 2017

Бинарные данные разбиваются, сериализуются и / или десериализуются.

Вы должны кодировать значения base64 перед добавлением их в массив сеансов, чтобы кодирование и декодирование сеансов не прерывалось.

$_SESSION['foo'] = base64_encode('bar0x0x0x0x');

или

$_SESSION['foo'] = [
    'fookey' => base64_encode('bar0x0x0x0x'),
    'fookey2' => base64_encode('bar0x0x0x0x')
];
0 голосов
/ 06 января 2010

Когда вы сериализуете глобальную переменную $ _SESSION, вы не захватите идентификатор сессии для этой конкретной сессии. Я уверен, что вам нужно использовать

$session_id = session_id();

и сохраните это вручную.

Руководство по PHP: http://php.net/manual/en/function.session-id.php

0 голосов
/ 06 января 2010

Обработка сеансов - это одна из волшебных вещей в PHP, которая «просто работает». Если вам нужно хранить ваши сеансы в БД, а не использовать файловую систему, вам нужно создать новый обработчик сеансов.

Я использовал старый порт обработчика сеансов Jon Parise postgres еще в 2003 году!

Нашел это у Зенда. Похоже, более обновленная информация.

http://devzone.zend.com/article/141

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

0 голосов
/ 06 января 2010

Почему вы хотите хранить данные сеанса в базе данных? Попробуйте записать данные base64_encode перед тем, как вставить их в БД

0 голосов
/ 06 января 2010

PHP делает свой собственный особый вид сериализации для сессий, и похоже, что сериализация происходит где-то. У меня нет доступа ко всему вашему коду, поэтому я не могу точно сказать, где. Если вы добавляете отладочный вывод в:

-Как выглядят данные перед сериализацией

-Как выглядят данные после сериализации

-Как выглядят данные, когда вы вставляете их в БД

-Как выглядят данные при извлечении их из БД

-Как выглядят данные сразу после десериализации.

Этого должно быть достаточно для диагностики проблем, связанных со встроенной сериализацией в PHP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...