Given
abstract class A {
public function __get($key) {
...
}
}
class B extends A {
public function __get($key) {
...
}
}
class C {
public function test($bObject) {
//Call the __get function of A on the object of B
}
}
How would I call A::__get on an object of B from C::test? I've looked into using a callable on class A::__get and binding it to the object of class B, or using parent, but neither of those methods seem to help.
In PHP one way you can do that is with reflection (introspection or also meta-programming), as by the class/object design, the encapsulation normally forbids it.
Given the following from the class definitions in question:
$b = new B();
$b->test;
It works by obtaining the closure of the parents method with the B object (e.g. the $bObject in your question or $b in the example here) and then calling it:
(new ReflectionObject($b))
->getParentClass()
->getMethod('__get')
->getClosure($b)('test'); // or: ->invoke($b, 'test');
Demo: https://3v4l.org/0tj26 and output for PHP 7.3.0 - 7.3.29, 7.4.0 - 7.4.21, 8.0.0 - 8.0.8:
string(8) "B::__get"
string(4) "test"
string(8) "A::__get"
string(4) "test"
Try using the ReflexionClass and the getParent method.
$objectB;
$key = 'key';
$reflectorB = new ReflectionObject($objectB);
$reflectorA = $reflectorB->getParentClass();
$method = $reflectorA->getMethod('__get');
return $method->invoke($objectB, $key);