Accessing private PHP class members per reference
This is quite an edge case, but a must-know if you do serious OOP PHP, since it actually gives some insights on how the engine can be worked around to share references across objects.
The idea may or may not interest you, since it's an obvious violation of OOP principles.
Use cases span across building serializers, greybox testing (not necessarily a good thing!), AOP frameworks, debugging and Data Mappers.
Given the following class:
class Kitchen {
private $yummy = 'cake';
}
And an instance of it:
$kitchen = new Kitchen();
We can now "steal" $yummy
from it using PHP 5.4's Closure::bind() method:
$cake = Closure::bind(function & () {
return $this->yummy;
}, $kitchen, $kitchen)->__invoke();
var_dump($reference);
$reference = 'the cake is a lie!'; // stole it!
var_dump($kitchen);
You can see a live example at http://3v4l.org/1q4KK
I also blogged more extensively on the usage of Closure::bind()
at http://ocramius.github.io/blog/accessing-private-php-class-members-without-reflection/
Written by Marco Pivetta
Related protips
7 Responses
Thanks for discovering 3v4l.org, didn't know that exists for PHP :)
good one
nice
Closure::bind seems pretty similar to Ruby's instance_eval
, or JavaScript's Function#bind
. Good to know that PHP has something like that!
@twisol yeah, PHP is a quite weird language. I still love and hate it all together :)
Little mixup with $cake and $reference ;)
ahhhwww... can't edit the post :(