PHP:如何重命名方法?

时间:2010-07-31 10:15:26

标签: php reflection

是否可以在运行时重命名PHP 5.2中的类方法?是否可以使用Reflection做到这一点?

假设:

class Test
{
    public function myMethod()
    {
        echo 'in my method';
    }
}

我希望能够将myMethod()重命名为oldMethod(),以便稍后我这样做:

$test = new Test();
$test->oldMethod(); // in my method
$test->myMethod(); // run time error: method does not exist

3 个答案:

答案 0 :(得分:4)

来自下面的评论问题:

  

因为我想在类上安装调用事件处理程序,而没有类知道它,所以我知道用户在实际调用该方法之前从类调用方法。

解决方案:使用装饰器。

class EventDecorator
{
    protected $_instance;
    public function __construct($instance)
    {
        $this->_instance = $instance;
    }
    public function __get($prop)
    {
        printf('Getting %s in %s', $prop, get_class($this->_instance));
        return $this->_instance->$prop;
    }
    public function __set($prop, $val)
    {
        printf('Setting %s with %s in %s',
            $prop, $val, get_class($this->_instance));
        return $this->_instance->$prop = $val;
    }
    public function __call($method, $args)
    {
        printf('Calling %s with %s in %s', 
            $method, var_export($args, TRUE), get_class($this->_instance));

        return call_user_func_array(array($this->_instance, $method), $args);
    }
}

然后你可以将任何一个类包装进去:

class Foo
{
    public $prop;
    public function doSomething() {}
}

$foo = new EventDecorator(new Foo);
$foo->prop = 'bar'; // Setting prop with bar in Foo    
$foo->prop;         // Getting prop in Foo
$foo->doSomething('something'); 
// Calling doSomething with array (0 => 'something',) in Foo

这可以充实以提供前钩和后钩。您还可以使Decorator使用Subject/Observer Pattern并将事件激发到注册到装饰器的任何其他对象。上面的方法比使用runkit的随机方法monkeypatching更易于维护和理解。

附加说明:

答案 1 :(得分:2)

使用Runkit s runkit_method_rename,您可以执行此操作。

答案 2 :(得分:1)

对于所有问你为什么需要这个的人,我有一个非常相似的想法。我的想法是尝试动态重命名整个PHP类。在我的情况下,它将被用于IRC聊天机器人,我将动态加载和实例化插件,这样我就不需要重新启动机器人,正常运行时间会非常长。这将包括重命名与我将尝试加载的类相同名称的预加载类,这样就不会发生冲突并且可以正常运行。

例如:

我在irc.example.com上运行了$bot

我已经安装并运行了插件test.php,现在当它被加载到内存中时,我可以更改文件test.php而不需要对$bot进行任何更改

所以我更新了test.php

现在我想让它加载到$bot,但是$bot已经有一个测试加载,如果我试图再次包含test.php会发生冲突

所以相反,我们运行一个重命名函数将类测试重命名为类test [计数器的sha1]

然后我们加入'test.php'

$bot->test = new test();

我们有了它,一个更新的测试插件安装并加载到$bot的内存中,没有重启。

这是所有的理论,但是在用“你为什么甚至需要这种”的态度立刻煽动某人的想法之前,要考虑一下。

我的意思是,让我们诚实一点。你是一个超级天才的几率是多少,他知道有关编程的所有知识,并会知道每个人都会或不需要什么?