#617: Check if Agavi is affected by PHP 5.2.4 get_object_vars() change
---------------------+------------------------------------------------------
 Reporter:  david    |        Owner:  david     
     Type:  task     |       Status:  closed    
 Priority:  low      |    Milestone:  0.11.1    
Component:  _OTHER_  |      Version:  0.11.0    
 Severity:  blocker  |   Resolution:  worksforme
 Keywords:           |  
---------------------+------------------------------------------------------
Changes (by david):

  * status:  assigned => closed
  * resolution:  => worksforme

Comment:

 Okay, does not affect us. Reproduce code (which did not work in 5.2.0 or
 so either):
 {{{
 class Foo {
         public $foo = 'foo';
         protected $bar = 'bar';
         private $baz = 'baz';
         public function __sleep() {
                 return get_object_vars($this);
         }
 }

 class Bar extends Foo {
 }

 $x = new Bar();
 var_dump($x->sleep());
 }}}
 yields
 {{{
 array(3) {
   ["foo"]=>
   string(3) "foo"
   ["bar"]=>
   string(3) "bar"
   ["baz"]=>
   string(3) "baz"
 }
 }}}

 However,
 {{{
 class Foo {
         public $foo = 'foo';
         protected $bar = 'bar';
         private $baz = 'baz';
 }

 class Bar extends Foo {
         public function __sleep() {
                 return get_object_vars($this);
         }
 }

 $x = new Bar();
 var_dump($x->__sleep());
 }}}
 returns
 {{{
 array(2) {
   ["foo"]=>
   string(3) "foo"
   ["bar"]=>
   string(3) "bar"
 }
 }}}
 (which is pretty strange given that {{{$this}}} should refer to the same
 instance in both cases; the calling scope to {{{get_object_vars()}}}
 apparently dictates the return value... funny PHP; let's hope they don't
 "fix" that as well)

 The change in 5.2.4 is about something different: calling
 {{{get_object_vars()}}} in a base class does not return a child's private
 members anymore.

 We do not have such a situation though. If we do, we need to call the
 parent, and then merge a little:
 {{{
 class Foo {
         public $foo = 'foo';
         protected $bar = 'bar';
         private $baz = 'baz';
         public function __sleep() {
                 return get_object_vars($this);
         }
 }

 class Bar extends Foo {
         private $lolz = 'ooh'; // this will not be seen by the parent dump
         public function __sleep() {
                 $elements = parent::__sleep();
                 $elements = array_merge($elements,
 array_diff(get_object_vars($this), $elements));
                 return $elements;
         }
 }

 $x = new Bar();
 var_dump($x->__sleep());
 }}}
 helps:
 {{{
 array(4) {
   ["foo"]=>
   string(3) "foo"
   ["bar"]=>
   string(3) "bar"
   ["baz"]=>
   string(3) "baz"
   ["lolz"]=>
   string(3) "ooh"
 }
 }}}


 = BUT: =
 Prior to 5.2.4, {{{get_object_vars($this)}}} returned using the scope of
 {{{$this}}}, not using the scope of the definition. As a consequence, you
 cannot subclass classes that have private variables and need to be
 serialized unless you use 5.2.4 or greater. This is the case with
 AgaviExecutionContainer, for instance.

-- 
Ticket URL: <http://trac.agavi.org/ticket/617#comment:2>
Agavi <http://www.agavi.org/>
An MVC Framework for PHP5


_______________________________________________
Agavi Tickets Mailing List
[email protected]
http://lists.agavi.org/mailman/listinfo/tickets

Reply via email to