#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