For some reasons I had the need to reimplement PHP's serialize() and unserialize() functions in userland. While the
Reflection API would be of great benefit for introspecting objects and grab the values of the object's properties it is not suited for this task - trying to read or set a protected or private property results in an ReflectionException. However, there are some ways to get around this restriction.
Getting the value of protected or private properties is somewhat simple: just cast the object to an array:
class Foo
{
public $foo = 'foo';
protected $bar = 'bar';
private $baz = 'baz';
}
$foo = new Foo();
$fooProperties = (array)$foo;
var_dump($fooProperties);
The result will look like:
array(3) {
["foo"]=>
string(3) "foo"
["\0*\0bar"]=>
string(3) "bar"
["\0Foo\0baz"]=>
string(3) "baz"
}
Now it is very simple to iterate over the array and grab the values of the respective property. Using this it is just a bunch of some more code to reimplement serialize() in userland. Reimplementing unserialize() is a bit trickier, because it is really hard to set protected and private properties (but not impossible).
Probably you already heard of
var_export(). Using this function returns a string that can be eval()'d, that is it gives you valid PHP code to execute. This code contains a method call
ClassName::__set_state(). Using this magic method you can recreate your object from userland unserialize(). Well, it is not that simple. It gets really tricky with nested objects and as soon as one of the objects you want to unserialize does not contain this method there is no way to set the protected and private properties.
So, whats the lesson from this? If PHP offers possibilities to read the value of protected and private properties (and with some hackish workarounds even to set them) anyway, why just not allow this within the Reflection API? No, "because it allows developers to shoot themself in their foot" is not a valid reason. Developers will always find a way to shoot themself in their foot, regardless of the measures you undertake to protect them.
By the way, it would be really nice if the reflection methods just return NULL instead of FALSE when something is not available. But that is another story about "the PHP way".