Skip to content

Instantly share code, notes, and snippets.

@guilhermeblanco
Last active May 25, 2017 02:31
Show Gist options
  • Save guilhermeblanco/4a7f39edd5c53e196b0f182ead815c71 to your computer and use it in GitHub Desktop.
Save guilhermeblanco/4a7f39edd5c53e196b0f182ead815c71 to your computer and use it in GitHub Desktop.
<?php
class Foo {
private $woo;
private $bar;
public function __construct($woo)
{
$this->woo = $woo;
}
public function setBar($bar) { $this->bar = $bar; }
public function getBar() { return $this->bar; }
public function getWoo() { return $this->woo; }
public function __clone() {
$this->woo = clone $this->woo;
}
}
$reflClass = new \ReflectionClass(Foo::class);
$fooProxy = $reflClass->newProxyInstance(
new MyCustomInvocationHandler(new Foo($someWoo)),
[ExtraInferface::class]
);
/*
interface \ReflectionProxyInvocationHandler {
public function invoke($objectInstance, $method, $arguments);
}
// However, Foo class properties, static members and methods are not copied over to anon class...
$fooProxy = new class(new MyInvocationHandler(new Foo($someWoo))) extends Foo implements ExtraInterface {
private $invocationHandler;
public function __construct(\ReflectionProxyInvocationHandler $invocationHandler)
{
$this->invocationHandler = $invocationHandler;
}
public static function __set_state(array $properties) { return $this->invocationHandler->invoke(null, __METHOD__, $properties); }
public static function __callStatic($method, $args) { return $this->invocationHandler->invoke(null, $method, $args); }
public function __call($method, $args) { return $this->invocationHandler->invoke($this, $method, $args); }
public function __invoke() { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __get($name) { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __set($name, $value) { $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __isset($name) { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __unset($name) { $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __clone() { $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __sleep() { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __wakeup() { $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __toString() { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
public function __debugInfo() { return $this->invocationHandler->invoke($this, __METHOD__, func_get_args()); }
}
*/
assertTrue($fooProxy instanceof ExtraInterface);
assertTrue($fooProxy instanceof Foo);
$fooProxy->setBar(2); // Goes through InvocationHandler > Foo instance
assertTrue($fooProxy->getBar() === 2);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment