Edit report at http://bugs.php.net/bug.php?id=52604&edit=1
ID: 52604
Comment by: isaiah dot derosewilson at kohanaphp dot com
Reported by: zerspam at mail dot ru
Summary: Serialization of objects with __sleep() and fatal
error
Status: Open
Type: Bug
Package: Session related
Operating System: irrelevant
PHP Version: Irrelevant
Block user comment: N
New Comment:
Tony, I guess I didn't explain myself very well. Serializable isn't the
problem. The issue is with the __wakeup/__sleep() methods.
Let's take these two example classes:
---------------
class myclass implements Serializable {
private $a = 1;
private $b = 2;
public function serialize()
{
return serialize(array('a' => $this->a));
}
public function unserialize($data)
{
foreach(unserialize($data) as $name => $var)
{
$this->{$name} = $var;
}
}
}
class myclass2 {
private $a = 1;
private $b = 2;
public function __sleep()
{
return array('a');
}
public function __wakeup()
{
}
}
I would expect both classes to serialize the 'a' property and they both
do. However when there is a fatal error in your code (like your example
code), both the a and b properties from the myclass2 class are
serialized.
Here is an example of my session data using your example code and the
two classes above.
Using Serializable:
obj|C:7:"myclass":18:{a:1:{s:1:"a";i:1;}} (without exception)
obj|N; (with exception)
Using sleep/wakeup:
obj|O:8:"myclass2":1:{s:11:"myclass2a";i:1;} (without exception)
obj|O:8:"myclass2":2:{s:11:"myclass2a";i:1;s:11:"myclass2b";i:2;} (with
exception)
Notice how when using the __sleep/__wakeup methods the whole object is
stored instead of nothing (or just the data in the __sleep method).
Hopefully that explains the issue a little better.
Previous Comments:
------------------------------------------------------------------------
[2010-10-13 08:10:45] [email protected]
Tony, if your argument would be valid, there wouldn't be anything in the
serssion at all, sould it?
------------------------------------------------------------------------
[2010-10-12 14:44:22] zerspam at mail dot ru
Uhm, in any case: wherther it is a error or not - I expected php does
not broke my data. And I cannot get how your sample related to mine.
With my code you can see that php stores the data it should not store.
And it is a error.
------------------------------------------------------------------------
[2010-10-12 14:24:52] [email protected]
>However if your class implements Serializable everything works as
>expected when there is a fatal error.
Not true.
See this example:
---------
set_error_handler('my_error_handler');
session_start();
$a->b();
class myclass implements Serializable
{
private $a= 1;
private $b = 2;
public function serialize()
{
var_dump("serialize");
return serialize(array('a'));
}
public function unserialize($data)
{
var_dump("unserialize");
return unserialize($data);
}
}
function my_error_handler($code, $error, $file = NULL, $line = NULL)
{
throw new ErrorException($error, $code, 0, $file, $line);
}
$obj = new myclass();
$_SESSION['obj'] = $obj;
---------
Whether your class implements Serializable or not, serializers are
called on _request shutdown_ which never happens in case of fatal error,
because fatal error means BOOM!, exit.
And to be honest, I don't see anything wrong here.
Your script FAILED with a fatal error, did you expect PHP to ignore it
an go on running?
------------------------------------------------------------------------
[2010-09-14 04:43:08] isaiah dot derosewilson at kohanaphp dot com
I also have this same problem. I've tested both php 5.2.12 and 5.3.3 and
neither of them correctly serialize the object when there is a fatal
error - the whole object gets serialized when there is a fatal error
instead of just the properties in __sleep(). However if your class
implements Serializable everything works as expected when there is a
fatal error.
------------------------------------------------------------------------
[2010-09-05 13:32:43] zerspam at mail dot ru
Well, 3 weeks left and even no comments from dev team?
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/bug.php?id=52604
--
Edit this bug report at http://bugs.php.net/bug.php?id=52604&edit=1