在运行时修改方法/函数

mon*_*nym 8 php reflection

我一直在看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)

可能?

irc*_*ell 6

好吧,一种方法是将所有方法调用"虚拟":

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()......

注意:您需要修改所有默认方法,并以"_"为前缀,以使其正常工作...(或者您可以选择其他前缀选项,或者您可以将它们全部保护为范围)...


Jar*_*les 2

研究匿名函数。如果您可以运行 PHP 5.3,那可能更符合您想要做的事情。