php - 在运行时修改方法/函数

标签 php reflection

我一直在研究 php 反射方法,我想做的是在方法打开之后和任何返回值之前注入(inject)一些代码,例如我想更改:

function foo($bar)
{
    $foo = $bar ;
    return $foo ;
}

然后向其中注入(inject)一些代码,例如:

function foo($bar)
{
    //some code here
    $foo = $bar ;
    //some code here
    return $foo ;
}

可能吗?

最佳答案

好吧,一种方法是使所有方法调用“虚拟”:

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

PHP 5.2:

$f = create_function('$obj, $str', 'echo "Bar: " . $obj->_doSomething($str) . " Baz";');

PHP 5.3:

$f = function($obj, $str) {
    echo "Bar: " . $obj->_doSomething($str) . " Baz";
}

所有 PHP:

$foo->addOverride('doSomething', $f);

$foo->doSomething('test'); // Bar: Foo: test Baz

它将对象的实例作为第一个方法传递给“覆盖”。注意:此“重写”方法将无法访问该类的任何 protected 成员。所以使用 getters (__get, __set)。它可以访问 protected 方法,因为实际调用来自 __call()...

注意:您需要将所有默认方法修改为带有“_”前缀才能正常工作...(或者您可以选择其他前缀选项,或者您可以只将它们全部保护起来)...

关于php - 在运行时修改方法/函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2931730/

相关文章:

java - 在 JPA 实体上查找声明的 java.util.Map 字段的泛型类型时出现 ClassNotFoundException (GlassFish 3)

c# - 使用反射将委托(delegate)连接到事件?

php - 设置语言环境(LC_CTYPE, "de_DE.UTF8")或设置语言环境(LC_CTYPE, "de_DE.UTF-8")?

php - 这两行 PHP 有何不同?

php - 将数字转换为热图 HTML 背景颜色的简单 PHP 函数?

php - MySQL 中的 If 或 CASE 语句

java - 从类类型实例化 C++ 中的类作为 std::map 值

php - 语言字符串加载失败 : from_failed[from_email_address]

java - 使用反射查找方法是否重载

c# - 如何: Define a Self Referenced Type Property with Reflection Emit in c#