Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save DougallWinship/dc54431707de71f1884238ed874744c2 to your computer and use it in GitHub Desktop.
Save DougallWinship/dc54431707de71f1884238ed874744c2 to your computer and use it in GitHub Desktop.
PHP trait (using magic methods and reflection) to interact with private attributes and methods in parent classes
trait AccessPrivate {
private static $ancestorReflectionClasses = null;
private static function getAncestorReflectionClasses()
{
if (is_null(self::$ancestorReflectionClasses)) {
$parentClasses = class_parents(self::class);
self::$ancestorReflectionClasses=[];
foreach ($parentClasses as $parentClass) {
self::$ancestorReflectionClasses[] = new \ReflectionClass($parentClass);
}
}
return self::$ancestorReflectionClasses;
}
private static function findParentReflectProperty($property)
{
$ancestorReflectionClasses = self::getAncestorReflectionClasses();
foreach ($ancestorReflectionClasses as $ancestorReflectionClass) {
if ($ancestorReflectionClass->hasProperty($property)) {
return $ancestorReflectionClass->getProperty($property);
}
}
throw new \ReflectionException("Property '".$property."' does not exist as an attribute of ".self::class." or it's parents");
}
private static function findParentReflectMethod($property)
{
$ancestorReflectionClasses = self::getAncestorReflectionClasses();
foreach ($ancestorReflectionClasses as $ancestorReflectionClass) {
if ($ancestorReflectionClass->hasMethod($property)) {
return $ancestorReflectionClass->getMethod($property);
}
}
throw new \ReflectionException("Property '".property."' does not exist as an method of ".self::class." or it's parents");
}
public function __call($method, $args)
{
$reflectMethod = self::findParentReflectMethod($method);
if ($reflectMethod->isPrivate()) {
$reflectMethod->setAccessible(true);
}
return $reflectMethod->invokeArgs($this, $args);
}
public function __get($name)
{
$reflectProperty = self::findParentReflectProperty($name);
if ($reflectProperty->isPrivate()) {
$reflectProperty->setAccessible(true);
}
return $reflectProperty->getValue($this);
}
public function __set($name, $value)
{
$reflectProperty = self::findParentReflectProperty($name);
if ($reflectProperty->isPrivate()) {
$reflectProperty->setAccessible(true);
}
return $reflectProperty->setValue($this,$value);
}
public static function __callStatic($name, $args)
{
$reflectStaticMethod = self::findParentReflectMethod($name);
if ($reflectStaticMethod->isPrivate()) {
$reflectStaticMethod->setAccessible(true);
}
return $reflectStaticMethod->invokeArgs(null, $args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment