简体   繁体   English

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

[英]PHP Storing Sessions: Can't Seem to Serialize Session Variables

I am making use of seralize and unseralize to set and get session variables from my Database. 我正在使用seralize和unseralize来设置和获取我的数据库中的会话变量。

A user is in a session and every time they click save. 用户在会话中并且每次单击保存。 I do this: 我这样做:

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

When a user loads a session, I load the variables too to continue that session like so: 当用户加载会话时,我也加载变量以继续该会话,如下所示:

//get row from DB
$_SESSION = unserialize($row['session_variables']);
  1. This doesn't work for me. 这对我不起作用。 It firstly doesn't unseralize as it returns something like this when I print_r($_SESSION) : 它首先不会取消分区,因为它在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. Where is the session_id for these variables to be used across different pages? 这些变量的session_id在不同的页面中使用在哪里? Have I over written them? 我写过了吗?

Thanks all for any help 谢谢大家的帮助

EDIT 编辑

Is the session_id kept in the global $_SESSION? session_id是否保存在全局$ _SESSION中? I am guessing no. 我猜不是。 If I unset $_SESSION, it means the session will not be gone just the variables, correct? 如果我取消设置$ _SESSION,这意味着会话不会只是变量,对吗? Anyone verify please? 有人验证吗?

Try this. 尝试这个。

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

Often times MySQL will not play nice with serialized data unless you base64_encode it. 通常情况下,MySQL不能很好地处理序列化数据,除非你对它进行base64_encode。 See if that helps. 看看是否有帮助。

You're going about this the wrong way. 你这是错误的方式。 Don't re-invent the wheel by trying to manually get -> serialize and unserialize -> set the session data 不要通过尝试手动获取 - >序列化和反序列化 - >设置会话数据来重新发明轮子

Instead, create a new session handler that will do the database work for you. 而是创建一个新的会话处理程序,它将为您的数据库工作。 The serialization/unserializtion is also handled for you - you won't have to explicitly call these functions. 序列化/非序列化也是为您处理的 - 您不必显式调用这些函数。 Also, by not using the established mechanism for this process, you're missing out on some functionality (like the session garbage collector) 此外,通过不使用已建立的机制进行此过程,您将错过某些功能(如会话垃圾收集器)

But before doing that, let's make a database table that will act as our session storage 但在此之前,让我们创建一个数据库表,作为我们的会话存储

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;

Next is to make a class with the methods we need. 接下来是用我们需要的方法创建一个类。 I'm not going to fill them all out - that's an exercise for you ;) 我不打算把它们全部填满 - 这对你来说是锻炼;)

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' )
    );
  }
}

And the basic usage would be 基本用法是

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

And as a final note, you can always get the current session ID just by calling session_id() 最后一点,您可以通过调用session_id()始终获取当前会话ID

PHP does its own special kind of serialization for sessions, and it looks like that serialization is happening somewhere. PHP为会话做了自己特殊的序列化,看起来序列化正在某个地方发生。 I don't have access to all of your code, so I can't really tell where. 我无法访问您的所有代码,因此我无法真正告诉您的位置。 If you add debug output to: 如果您将调试输出添加到:

-What the data looks like before you serialize - 序列化之前的数据是什么样的

-What the data looks like after you serialize - 序列化后数据是什么样的

-What the data looks like when you insert it into the DB - 将数据插入数据库时​​的数据是什么样的

-What the data looks like when you fetch it from the DB - 从数据库中获取数据时的数据

-What the data looks like immediately after you unserialize. - 反序列化后,数据会立即显示。

That should be enough info to diagnose where PHP's built in serialization is causing problems. 这应该足以诊断PHP内置序列化导致问题的位置。

Why do you want to store session data in database? 为什么要将会话数据存储在数据库中? Try to base64_encode data before putting in into DB 在插入数据库之前尝试base64_encode数据

Session handling is one of the magic things in PHP that "just works". 会话处理是PHP中“正常工作”的神奇之处。 If you need to store your sessions in a db instead of using the filesystem you'll need to build new session handler. 如果您需要将会话存储在数据库而不是使用文件系统,则需要构建新的会话处理程序。

I've been using an old port of the Jon Parise postgres session handler from way back in 2003! 从2003年开始,我一直在使用Jon Parise postgres会话处理程序的旧端口!

Found this at Zend. 在Zend找到了这个。 Looks like more updated information. 看起来更新的信息。

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

In short, just forcing the data into the database and retrieving it with your own serialize stuff won't cut it. 简而言之,只是强制数据进入数据库并使用您自己的序列化内容检索它不会削减它。 You nee to do the full session handler to know it's going to work everywhere. 你需要做完整的会话处理程序,知道它将在任何地方工作。

When you serialize the $_SESSION global you won't capture the session id for that particular session. 序列化$ _SESSION全局时,您将不会捕获该特定会话的会话ID。 I'm pretty sure you need to use 我很确定你需要使用

$session_id = session_id();

and save that manually. 并手动保存。

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

Binary data breaks serialize and/or unserialize. 二进制数据中断序列化和/或反序列化。

You should base64 encode values before adding them to the session array so that session encoding and decoding do not break. 在将值添加到会话数组之前,您应该对其进行base64编码,以便会话编码和解码不会中断。

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

or 要么

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM