PHP Accessing Protected / Private Properties

<?php// Demo code - using closure / reflection to expose private properties.class HasPrivate {
// Public members.
public $a;

// Restricted members.
private $b;
private $c;
private function square($val) {
return $val * $val;
}
public function __construct() {
$this->a = 123;
$this->b = 999;
$this->c = 2;
}
}
// Create instance of class with a private property "b".
$hp = new HasPrivate();
// Use closure bound to scope of class to access private property.
// see https://www.php.net/manual/en/closure.bind.php
$closuremethod = Closure::bind(function($hp) {
return $hp->b;
}, null, get_class($hp));
// Here is the property recovered by the closure.
$byclosure = $closuremethod($hp);
echo "\n\n Value recovered by closure ".$byclosure;// Use reflection to access private property.
// see https://www.php.net/manual/en/reflectionproperty.getvalue.php
$rc = new ReflectionClass($hp);
$prop = $rc->getProperty('b');
$prop->setAccessible(true);
$byreflection = $prop->getValue($hp);
echo "\n\n Value recovered by reflection ".$byreflection;// CLOSURE BENEFITS - can do more at once with less code!
// Use closure bound to scope of class to access multiple private members!
// see https://www.php.net/manual/en/closure.bind.php
$multiply = Closure::bind(function($hp) {
// Call private method to calculate multiple private properties.
return $hp->square($hp->b * $hp->c);
}, null, get_class($hp));
// Calculation based on private stuff in $hp object.
$calculated = $multiply($hp);
echo "\n\n Calculated value recovered by closure ".$calculated;

Closures Pros/Cons

The first thing that I like about this technique is that you can do much more in one go than you can with reflection. Because we are binding a function to the scope of a class it acts almost like a method within that class, which means that if I wanted to access multiple private members in one go, or process them in some way, I can do so with less code. Say for example I want to multiply a private property by a private property I can do that all in one go inside the closure:

$closuremethod = Closure::bind(function($hp) {
return $hp->b * $hp->c;
}, null, get_class($hp));
// Here is the property recovered by the closure.
$byclosure = $closuremethod($hp);
$multiply = Closure::bind(function($hp) {
// Call private method to calculate multiple private properties.
return $hp->square($hp->b * $hp->c);
}, null, get_class($hp));

Reflection Pros/Cons

What I really like about this technique is readability. It takes minimal mental effort for me to understand what it’s doing and I don’t need any comments to explain it. However, for the sake of those new to reflection, here’s some comments added explaining what it’s doing:

// Create a reflection class of the $hp instance.
$rc = new ReflectionClass($hp);
// Get the reflection property for the private property b.
$prop = $rc->getProperty('b');
// Make this property accessible so we can read its value.
$prop->setAccessible(true);
// Get the value of the property now we've made it accessible.
$value = $prop->getValue($hp);

Conclusion

So there you have it! Binding a closure to a class gives you the ability to do more with restricted members in one go but sacrifices readability to a degree. Going forward, I will definitely be using this technique where appropriate instead of reflection.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store