php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #49432 $_SESSION cannot store objects and resources
Submitted: 2009-09-01 17:14 UTC Modified: 2009-11-13 22:25 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: jost dot boekemeier at googlemail dot com Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: Irrelevant OS: Any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
48 + 48 = ?
Subscribe to this entry?

 
 [2009-09-01 17:14 UTC] jost dot boekemeier at googlemail dot com
Description:
------------
The session documentation does not make it clear that PHP cannot (logically and in its current implementation) store objects or resources.

This lack of specification makes it hard for external libraries to respond to bug reports like this one: http://bugs.php.net/bug.php?id=13840&edit=1.
(BTW: In bug#13840 Mr. Holzgreve states that "php sessions can store every PHP data type including objects". This is clearly WRONG and shows that even PHP devs don't understand the PHP scripting language.)

We've had a similar bug report for the PHP/Java Bridge. This person wanted to store a Java object into the session.

Please add the following to the _SESSION documentation:

"PHP sessions can only store PHP /values/, for example exact or inexact numbers. They *cannot* store any other PHP data types, including resources and objects. If you want to store complex data in the session, serialize the data into a string value first."

Please note that I have filed this as a documentation bug, not a bug in the PHP implementation. 

Reproduce code:
---------------
<?php

class X {
  var $destroyed;
  
  function __sleep() { echo "s"; if ($this->destroyed) { echo("\nerror: destroyed"); sleep (10); exit(1);} /*not reached*/ }
  function __destruct() { echo "d"; $this->destroyed = true; }
  function __construct() { echo "c"; $this->destroyed = false; }

}

session_start();
$x= new X();
$_SESSION["X"]=$x;


?>


Expected result:
----------------
The above script should not call __destruct() before __sleep();

Actual result:
--------------
__destruct() is called before __sleep()

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-09-01 19:20 UTC] preinheimer at gmail dot com
Objects can in fact be stored in sessions. They are serialized for storage, the __sleep() and __wakeup() magic methods have been created to add functionality to the process.

Clarification regarding resources could be added to the current note on references to make things more clear.
 [2009-09-01 19:56 UTC] preinheimer at gmail dot com
to clarify further. 

CSD can be obtained, rather than CDS through the use of session_write_close().


If you'd like to argue for better documentation on shutdown order, or the fact that both the destructor and _sleep() are called when the script ends, that might be fair. But sessions can indeed store objects. 

note that X is actually destroyed, You've stored a serialized copy inside _SESSION, but there's that copy outside session as well, it is destroyed when the script ends.
 [2009-09-01 20:20 UTC] jost dot boekemeier at googlemail dot com
[Please don't take bug reports lightly]

> Objects can in fact be stored in sessions.

No, they can't. See the php demo attached to this ticket.
IF you want to make php objects finalizable, you must introduce a new api, similar to 
Scheme's or Java's weak refs.

> They are serialized fo storage, the __sleep() and __wakeup() magic methods have 
bee

_sleep() is useless as it is called long after the objects have been nuked.

It's a chicken/egg problem. PHP must call _destruct() before it can call the session 
save handler. Therefore the handler cannot do much with the destroyed objects 
anymore.
 [2009-09-01 22:37 UTC] jost dot boekemeier at googlemail dot com
> CSD can be obtained, rather than CDS through the use o session_write_close

A PHP library needs a reliable PHP behaviour. The library cannot force users to use 
or not use session_write_close() to properly write a session.

When __destroy() is called before __sleep(). the library has no other choice than to 
throw an exception telling the user that the object has already been destroyed by 
php. As a result users of the library report a bug to the library author.

I am trying to avoid these bug reports.
 [2009-09-02 14:01 UTC] preinheimer at gmail dot com
PHP can store objects in sessions. 
http://example.preinheimer.com/sessobj.php

The shutdown order (destruction before serialization) is likely faulty. Please file a bug against the language for that issue.
 [2009-09-02 14:19 UTC] colder@php.net
Actually, it a choice we have to make: first destroy objects or first terminate sessions.

Currently, we first call __destruct on objects, then terminate sessions.

This has the advantage of allowing objects destroyed at shutdown to still be able to manage session data.

The only drawback is that __sleep() gets called after __destruct which you discovered here. So maybe we should add a notice to __sleep's documentation.
 [2009-09-02 15:54 UTC] jost dot boekemeier at googlemail dot com
I think the problem is that PHP currently does not support session objects which in turn manage external resources or implement __sleep()/__destruct() for other reasons. 

This problem could be fixed by introducing a "Finalizable" tagging interface. Objects implementing this interface will not be destroyed before rshutdown, but added to a internal "finalizable_list". This list is then traversed by the session module to call __sleep() on each object in the list. After rshutdown the gc will examine the finalizable_list again and destruct all objects in the list.

That means: Objects implementing the "Finalizable" interface will receive __sleep() before __destruct(), for all other objects the behaviour stays the same.

I think this should be easy to implement and won't break existing applications or libraries.

I will open a new ticket for this.

Thank you very much!
 [2009-11-13 22:25 UTC] vrana@php.net
Already documented at http://www.php.net/manual/en/intro.session.php: "Some types of data can not be serialized thus stored in sessions. It includes resource variables"
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 22:01:26 2024 UTC