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

PHP存储会话:Can';似乎无法序列化会话变量,php,session,serialization,variables,Php,Session,Serialization,Variables,我正在使用seralize和unseralize从数据库中设置和获取会话变量 用户正在会话中,每次单击“保存”。我这样做: $array = serialize($_SESSION); //and save to DB field 当用户加载会话时,我也加载变量以继续该会话,如下所示: //get row from DB $_SESSION = unserialize($row['session_variables']); 这对我不管用。它首先不会失去士气,因为当Iprint\r($\u S

我正在使用seralize和unseralize从数据库中设置和获取会话变量

用户正在会话中,每次单击“保存”。我这样做:

$array = serialize($_SESSION);
//and save to DB field
当用户加载会话时,我也加载变量以继续该会话,如下所示:

//get row from DB
$_SESSION = unserialize($row['session_variables']);
  • 这对我不管用。它首先不会失去士气,因为当I
    print\r($\u SESSION)
    时,它会返回如下内容:

  • 这些变量在不同页面上使用的会话id在哪里?我写得太多了吗

  • 谢谢大家的帮助

    编辑
    会话id是否保存在全局$会话中?我猜不会。如果我取消设置$\u会话,这意味着会话不会消失,只是变量,对吗?有人验证吗?

    PHP为会话执行自己的特殊类型的序列化,看起来序列化正在某处发生。我无法访问你所有的代码,所以我真的不知道在哪里。如果将调试输出添加到:

    -序列化之前数据的外观

    -序列化后数据的外观

    -将数据插入数据库时数据的外观

    -从数据库中获取数据时数据的外观

    -取消序列化后数据的外观

    这应该足以诊断PHP内置序列化在何处导致问题。

    试试这个

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

    通常情况下,MySQL不会很好地处理序列化数据,除非您对其进行base64_编码。看看这是否有帮助。

    为什么要在数据库中存储会话数据?
    在将数据放入DB之前,尝试对数据进行base64_编码会话处理是PHP中“正常工作”的神奇功能之一。如果需要将会话存储在数据库中而不是使用文件系统,则需要构建新的会话处理程序

    从2003年开始,我就一直在使用Jon Parise postgres会话处理程序的旧端口

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


    简言之,仅仅将数据强制放入数据库并用自己的序列化内容检索数据并不能解决问题。您需要执行完整的会话处理程序,以知道它将在任何地方工作。

    当您序列化$\u全局会话时,您将不会捕获该特定会话的会话id。我很确定你需要使用

    $session_id = session_id();
    
    然后手动保存


    PHP手册:

    您的做法是错误的。不要试图通过手动获取->序列化和取消序列化->设置会话数据来重新发明控制盘

    相反,创建一个新的会话处理程序来为您完成数据库工作。序列化/非序列化也为您处理-您不必显式调用这些函数。此外,如果不使用此流程的既定机制,您将错过一些功能(如会话垃圾收集器)

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

    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;
    
    接下来是用我们需要的方法创建一个类。我不会把它们全部填好——这是你的练习;)

    基本用法是

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

    最后一点,只要调用

    二进制数据中断序列化和/或取消序列化,就可以始终获得当前会话ID

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

    $\u会话['foo']=base64\u编码('bar0x0x')


    这似乎对我不起作用。结果还是一样。顺便说一句,我正在使用SQL Server。好吧,在再次查看我的脚本之后,上面的内容对我来说很有用!谢谢Joe。我只是想保存一个简单的会话变量,这样我的web应用程序就可以有某种状态,而不仅仅是会话。我不想要一个基于数据库的会话系统!我只是将这些变量存储起来以备将来使用,然后将它们检索回来。这超出了会话的生命周期!如果我不能解决上述问题,我想我会让事情变得简单。可能只是在我的数据库中每个字段坚持一个值-这是我以前的做法,我认为这会更有效,并随着我和我的应用程序扩展。但如果我更新整个$\u会话全局数组,我不会重置或设置任何内容-这正是我想要的!)我只是不能让人觉得不道德(感谢您的回复Peter。但是,我不想实现基于数据库的会话。我只需要将某些变量存储在全局$\u会话数组中,以供以后(几天、几周)使用。
    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['foo'] = [
        'fookey' => base64_encode('bar0x0x0x0x'),
        'fookey2' => base64_encode('bar0x0x0x0x')
    ];