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] m...@php.net

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] tony2...@php.net

>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

Reply via email to