<?php
class Proxy
{
private $object;
private $onEnter = [];
private $onLeave = [];
public function __registerOnEnter($method, \Closure $closure)
{
$this->onEnter[$method][] = $closure;
}
private function invokeOnEnter($method, array $arguments)
{
if (empty($this->onEnter[$method]))
{
return;
}
foreach ($this->onEnter[$method] as $closure)
{
call_user_func($closure, $this->object, $arguments);
}
}
public function __registerOnLeave($method, \Closure $closure)
{
$this->onLeave[$method][] = $closure;
}
private function invokeOnLeave($method, array $arguments)
{
if (empty($this->onLeave[$method]))
{
return;
}
foreach ($this->onLeave[$method] as $closure)
{
call_user_func($closure, $this->object, $arguments);
}
}
private function getProxiedMethod($method)
{
$methodReflection = new \ReflectionMethod($this->object, $method);
return $methodReflection->getClosure($this->object)->bindTo($this);
}
public function __call($method, array $arguments)
{
$this->invokeOnEnter($method, $arguments);
call_user_func_array($this->getProxiedMethod($method), $arguments);
$this->invokeOnLeave($method, $arguments);
}
public function __construct($object)
{
$this->object = (object) $object;
}
}
class Foo
{
public function bar()
{
$this->qux();
}
public function qux()
{
$this->zip();
}
public function zip()
{
var_dump(__CLASS__);
}
}
$fooProxy = new Proxy(new Foo());
$fooProxy->__registerOnEnter('bar', function ($object) {
var_dump(sprintf('%s::bar#onEnter', get_class($object)));
});
$fooProxy->__registerOnLeave('bar', function ($object) {
var_dump(sprintf('%s::bar#onLeave', get_class($object)));
});
$fooProxy->__registerOnEnter('qux', function ($object) {
var_dump(sprintf('%s::qux#onEnter', get_class($object)));
});
$fooProxy->__registerOnLeave('qux', function ($object) {
var_dump(sprintf('%s::qux#onLeave', get_class($object)));
});
$fooProxy->__registerOnEnter('zip', function ($object) {
var_dump(sprintf('%s::zip#onEnter', get_class($object)));
});
$fooProxy->__registerOnLeave('zip', function ($object) {
var_dump(sprintf('%s::zip#onLeave', get_class($object)));
});
$fooProxy->bar();
preferences:
37.17 ms | 402 KiB | 5 Q