Last active
May 24, 2018 12:33
-
-
Save jkrzefski/a22402bbe45b6035c32ad445e1d623ac to your computer and use it in GitHub Desktop.
This "hack" grants external callers read-, write- and execution-access to private and protected members of an instance. Beware that this violates the idea of oop and should therefore only be the last resort before giving up.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Closure; | |
use Exception; | |
use ReflectionException; | |
use ReflectionMethod; | |
/** | |
* Class AccessEnforcer | |
*/ | |
class AccessEnforcer | |
{ | |
/** | |
* Reads a private attribute of the given | |
* instance. Cannot read private attributes | |
* of any parent classes. | |
* | |
* @param $instance | |
* @param $name | |
* @return mixed | |
* @throws Exception | |
*/ | |
public static function forceRead($instance, $name) | |
{ | |
if (!is_object($instance)) { | |
throw new Exception('$instance must be an object.'); | |
} | |
$spoof = Closure::bind(function ($instance) use ($name) { | |
return $instance->{$name}; | |
}, null, $instance); | |
return $spoof($instance); | |
} | |
/** | |
* Writes a value to a specific private | |
* attribute of the given instance. | |
* Cannot override private attributes of | |
* any parent classes. | |
* | |
* @param $instance | |
* @param $name | |
* @param $value | |
* @throws Exception | |
*/ | |
public static function forceWrite($instance, $name, $value) | |
{ | |
if (!is_object($instance)) { | |
throw new Exception('$instance must be an object.'); | |
} | |
$spoof = Closure::bind(function ($instance) use ($name, $value) { | |
$instance->{$name} = $value; | |
}, null, $instance); | |
$spoof($instance); | |
} | |
/** | |
* Calls a private method of the given | |
* instance with the given parameters | |
* and returns its return value. | |
* | |
* @param $instance | |
* @param $name | |
* @param array ...$arguments | |
* @return mixed | |
* @throws Exception | |
* @throws ReflectionException | |
*/ | |
public static function forceCallMethod($instance, $name, ...$arguments) | |
{ | |
if (!is_object($instance)) { | |
throw new Exception('$instance must be an object.'); | |
} | |
$method = new ReflectionMethod(get_class($instance), $name); | |
$method->setAccessible(true); | |
return $method->invoke($instance, ...$arguments); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment