我一直在看php反射方法,我想要做的是在方法打开之后和任何返回值之前注入一些代码,例如我想要更改:
function foo($bar)
{
$foo = $bar ;
return $foo ;
}
Run Code Online (Sandbox Code Playgroud)
并注入一些代码,如:
function foo($bar)
{
//some code here
$foo = $bar ;
//some code here
return $foo ;
}
Run Code Online (Sandbox Code Playgroud)
可能?
好吧,一种方法是将所有方法调用"虚拟":
class Foo {
protected $overrides = array();
public function __call($func, $args) {
$func = strtolower($func);
if (isset($this->overrides[$func])) {
// We have a override for this method, call it instead!
array_unshift($args, $this); //Add the object to the argument list as the first
return call_user_func_array($this->overrides[$func], $args);
} elseif (is_callable(array($this, '_' . $func))) {
// Call an "internal" version
return call_user_func_array(array($this, '_' . $func), $args);
} else {
throw new BadMethodCallException('Method '.$func.' Does Not Exist');
}
}
public function addOverride($name, $callback) {
$this->overrides[strtolower($name)] = $callback;
}
public function _doSomething($foo) {
echo "Foo: ". $foo;
}
}
$foo = new Foo();
$foo->doSomething('test'); // Foo: test
Run Code Online (Sandbox Code Playgroud)
PHP 5.2:
$f = create_function('$obj, $str', 'echo "Bar: " . $obj->_doSomething($str) . " Baz";');
Run Code Online (Sandbox Code Playgroud)
PHP 5.3:
$f = function($obj, $str) {
echo "Bar: " . $obj->_doSomething($str) . " Baz";
}
Run Code Online (Sandbox Code Playgroud)
所有PHP:
$foo->addOverride('doSomething', $f);
$foo->doSomething('test'); // Bar: Foo: test Baz
Run Code Online (Sandbox Code Playgroud)
它将对象的实例作为第一个方法传递给"覆盖".注意:此"覆盖"方法将无法访问该类的任何受保护成员.所以使用getters(__get
,__set
).它可以访问受保护的方法,因为实际的呼叫来自__call()
......
注意:您需要修改所有默认方法,并以"_"为前缀,以使其正常工作...(或者您可以选择其他前缀选项,或者您可以将它们全部保护为范围)...