简体   繁体   中英

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.

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

     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? Have I over written them?

Thanks all for any help

EDIT

Is the session_id kept in the global $_SESSION? I am guessing no. If I unset $_SESSION, it means the session will not be gone just the variables, correct? 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. 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()

PHP does its own special kind of serialization for sessions, and it looks like that serialization is happening somewhere. 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.

Why do you want to store session data in database? Try to base64_encode data before putting in into DB

Session handling is one of the magic things in PHP that "just works". 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!

Found this at Zend. Looks like more updated information.

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. 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

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.

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

or

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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