tags:

views:

1170

answers:

4

The PHP documentation says "You can't use references in session variables as there is no feasible way to restore a reference to another variable."

Does this mean I can't have things like:

session_start();
$user =new User;
$user->name='blah';
$_SESSION['user']=$user;

I have tried to store a simple string and a User object in session, the string always persists between pages to pages, or after page refresh. However the User variable is lost in $_SESSION(becomes empty).

any idea?

Edit: I have confirmed that session_id is the same in all of these pages/subpages,before & after page refresh.

Edit: Strangely, after I tried serialize and unserialize approach below, the serialized user object(or string) in session still still disappears!

Edit: finally I figured out what the bug was, looks like somehow $_SESSION['user'] gets overwritten by some mysterious force, if I use any variable other than 'user', then everything's fine. PHP(at least 5.3 which is the version I'm using) does serialize and unserialize automatically when you put object in the $_SESSION.

session_start();
$user=new User();
$user->name='blah'
$_SESSION['myuser']=$user; 
+1  A: 

Try serializing the object, and storing it as a string: PHP Serializing Objects

Marius
+1 for agreeing and similar name =D
thephpdeveloper
but shouldn't I be able to store complex object in session?
Yes, serializing allows you to do that.
jimyi
php's session implementation has serialization built in for any serializable type, so you never have to manually serialize/unserialize anything you put into the `$_SESSION`, including objects.
JPot
-1. Agreed with JPot's comment.
fireeyedboy
A: 

That's the expected behavior. Storing a reference to an object would only work if the memory location for the object didn't change. In a stateless protocol like HTTP, application state is not persisted between requests. The next request may be handled on another thread, process, or another server.

Given the inherent stateless nature of a web application, holding a pointer to a memory location is useless. Therefore the object's state must be broken down into a storage format, saved or transmitted, and then reconstituted when needed. This process is known as Serialization.

You can choose to serialize the entire object into session (which maybe dangerous depending on the depth of your object graph, since your object may hold references to other objects and those would need to be serialized as well), or if the object can be reconstituted by querying the database on the next request you may just stash an ID in the session.

[EDIT]

JPot pointed out that objects are automatically serialized to $_SESSION, so explicit serialization isn't necessary. I'll leave the answer for posterity, but obviously it doesn't help your problem.

gbc
php's session implementation has serialization built-in: it automatically serializes serializable types (includes native types).
JPot
From the PHP docs: "If you are using sessions and use session_register() to register objects, these objects are serialized automatically at the end of each PHP page, and are unserialized automatically on each of the following pages." This makes it sound like types are only automatically serialized when registered. Otherwise, the docs example show objects being explicitly serialized. Is that inaccurate?
gbc
The docs show objects being explicitly serialized because that page is about how to serialize objects. The blurb about session_register() is only loosely tied to serialization. It's saying basically you don't need to serialize objects explicitly to use them in sessions.
JPot
OK, thanks. I misread that passage in the docs, appreciate the clarification.
gbc
+2  A: 

You need to use the magic __sleep and __wakeup methods for PHP 5 Objects.

For example in the following code block:

$obj = new Object();

$_SESSION['obj'] = serialize($obj);

$obj = unserialize($_SESSION['obj']);

__sleep is called by serialize(). A sleep method will return an array of the values from the object that you want to persist.

__wakeup is called by unserialize(). A wakeup method should take the unserialized values and initialize them in them in the object.

Noah Goodrich
+2  A: 

Your code example isn't using references as the documentation was referring to. This is what php means by references:

$var =& $GLOBALS["var"];

As to putting objects into the session, PHP can store objects in $_SESSION. See http://example.preinheimer.com/sessobj.php.

What you are seeing is a bug in the order of calls to __sleep and __destruct (__destruct is being called before __sleep) and the session module fails to serialize the object at shutdown. This bug was opened on Sep 1, 2009.

JPot