PHP存储会话:似乎无法序列化会话变量

时间:2010-01-05 21:59:47

标签: php session serialization variables

我正在使用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在不同的页面中使用在哪里?我有没有写过它们?

  3. 感谢大家的帮助

    修改

    session_id是否保存在全局$ _SESSION中?我猜不是。如果我取消设置$ _SESSION,这意味着会话不会只是变量,对吗?有人确认吗?

7 个答案:

答案 0 :(得分:7)

试试这个。

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

除非你对它进行base64_encode,否则MySQL通常不能很好地处理序列化数据。看看是否有帮助。

答案 1 :(得分:2)

你这是错误的方式。不要通过尝试手动获取 - >重新发明轮子。序列化和反序列化 - >设置会话数据

相反,创建一个新的会话处理程序,它将为您执行数据库工作。序列化/非序列化也是为您处理的 - 您不必显式调用这些函数。此外,通过不使用已建立的机制进行此过程,您错过了一些功能(如会话垃圾收集器)

但在此之前,让我们创建一个充当会话存储的数据库表

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()

即可获得当前的会话ID

答案 2 :(得分:0)

PHP为会话做了自己特殊的序列化,看起来序列化正在某处发生。我无法访问您的所有代码,因此我无法真正告诉您的位置。如果将调试输出添加到:

- 序列化之前的数据是什么样的

- 序列化后的数据是什么样的

- 将数据插入数据库时​​的数据是什么

- 从数据库中获取数据时的数据是什么

- 反序列化后,数据会立即显示。

这应该足以诊断PHP内置序列化导致问题的位置。

答案 3 :(得分:0)

为什么要将会话数据存储在数据库中? 在插入数据库之前尝试base64_encode数据

答案 4 :(得分:0)

会话处理是PHP中“正常工作”的神奇之处。如果您需要将会话存储在数据库而不是使用文件系统,则需要构建新的会话处理程序。

我从2003年开始使用Jon Parise postgres会话处理程序的旧端口!

在Zend找到了这个。看起来更新的信息。

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

简而言之,只是强制数据进入数据库并使用您自己的序列化内容检索它不会削减它。你需要做一个完整的会话处理程序,知道它可以在任何地方工作。

答案 5 :(得分:0)

序列化$ _SESSION全局时,您将无法捕获该特定会话的会话ID。我很确定你需要使用

$session_id = session_id();

并手动保存。

PHP手册:http://php.net/manual/en/function.session-id.php

答案 6 :(得分:0)

二进制数据中断序列化和/或反序列化。

在将值添加到会话数组之前,您应该对其进行base64编码,以便会话编码和解码不会中断。

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

$_SESSION['foo'] = [
    'fookey' => base64_encode('bar0x0x0x0x'),
    'fookey2' => base64_encode('bar0x0x0x0x')
];