Last active
September 2, 2021 21:27
-
-
Save goodevilgenius/c34b5027dc5d6fe6677d81b32bdd397d to your computer and use it in GitHub Desktop.
Class to access private/protected methods/properties without Reflections. Requires PHP 8 (could be rewritten to support 7)
This file contains hidden or 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 | |
| declare(strict_types=1); | |
| class ClassProxy | |
| { | |
| protected ?string $class; | |
| protected ?object $object; | |
| protected Closure $caller; | |
| protected Closure $getter; | |
| protected Closure $setter; | |
| public function __construct($classOrObject) | |
| { | |
| [$this->object, $this->class] = is_object($classOrObject) ? | |
| [$classOrObject, get_class($classOrObject)] : | |
| ( | |
| is_string($classOrObject) && class_exists($classOrObject) ? | |
| [null, $classOrObject] : | |
| [null, null] | |
| ); | |
| $this->initCaller(); | |
| $this->initGetter(); | |
| $this->initSetter(); | |
| } | |
| protected function initCaller(): void | |
| { | |
| $this->caller = ( | |
| $this->object ? | |
| fn (string $method, array $args) => $this->$method(...$args) : | |
| fn (string $method, array $args) => static::$method($args) | |
| )->bindTo($this->object, $this->class); | |
| } | |
| protected function initGetter(): void | |
| { | |
| $this->getter = ( | |
| $this->object ? | |
| fn (string $key) => $this->$key : | |
| fn (string $key) => static::$$key | |
| )->bindTo($this->object, $this->class); | |
| } | |
| protected function initSetter(): void | |
| { | |
| $this->setter = ( | |
| $this->object ? | |
| fn (string $key, $value) => $this->$key = $value : | |
| fn (string $key, $value) => static::$$key = $value | |
| )->bindTo($this->object, $this->class); | |
| } | |
| public function call(callable $cb, ...$args) | |
| { | |
| return (\Closure::fromCallable($cb)->bindTo($this->object, $this->class))(...$args); | |
| } | |
| public function __call(string $method, array $args) | |
| { | |
| return ($this->caller)($method, $args); | |
| } | |
| public function __get(string $key) | |
| { | |
| return ($this->getter)($key); | |
| } | |
| public function __set(string $key, $value) | |
| { | |
| return ($this->setter)($key, $value); | |
| } | |
| } | |
| function spy($classOrObject): ClassProxy | |
| { | |
| return new ClassProxy($classOrObject); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment