在PHP中为已经实例化的对象添加自定义函数?

时间:2009-08-17 15:50:12

标签: php oop function class

在PHP中做这样的事情的最佳方法是什么?:

$a = new CustomClass();

$a->customFunction = function() {
    return 'Hello World';
}

echo $a->customFunction();

(以上代码无效。)

3 个答案:

答案 0 :(得分:7)

这是一个简单且有限的类似猴子补丁的PHP类。添加到类实例的方法必须将对象引用($this)作为其第一个参数python-style。 此外,parentself等结构也无效。

OTOH,它允许你修补任何callback type到班级。

class Monkey {

    private $_overload = "";
    private static $_static = "";


    public function addMethod($name, $callback) {
        $this->_overload[$name] = $callback;
    }

    public function __call($name, $arguments) {
        if(isset($this->_overload[$name])) {
            array_unshift($arguments, $this);
            return call_user_func_array($this->_overload[$name], $arguments);
            /* alternatively, if you prefer an argument array instead of an argument list (in the function)
            return call_user_func($this->_overload[$name], $this, $arguments);
            */
        } else {
            throw new Exception("No registered method called ".__CLASS__."::".$name);
        }
    }

    /* static method calling only works in PHP 5.3.0 and later */
    public static function addStaticMethod($name, $callback) {
        $this->_static[$name] = $callback;
    }

    public static function __callStatic($name, $arguments) {
        if(isset($this->_static[$name])) {
            return call_user_func($this->_static[$name], $arguments);
            /* alternatively, if you prefer an argument list instead of an argument array (in the function)
            return call_user_func_array($this->_static[$name], $arguments);
            */
        } else {
            throw new Exception("No registered method called ".__CLASS__."::".$name);
        }
    }

}

/* note, defined outside the class */
function patch($this, $arg1, $arg2) {
    echo "Arguments $arg1 and $arg2\n";
}

$m = new Monkey();
$m->addMethod("patch", "patch");
$m->patch("one", "two");

/* any callback type works. This will apply `get_class_methods` to the $m object. Quite useless, but fun. */
$m->addMethod("inspect", "get_class_methods");
echo implode("\n", $m->inspect())."\n";

答案 1 :(得分:2)

与Javascript不同,您不能在事后将函数分配给PHP类(我假设您来自Javascript,因为您使用的是匿名函数)。

Javascript有一个Classless Prototypal系统,PHP有一个经典的分类系统。在PHP中,您必须定义要使用的每个类,而在Javascript中,您可以根据需要创建和更改每个对象。

用道格拉斯·克罗克福德的话来说:你可以在Javascript中编程,就像它是一个经典系统,但是你不能像经典系统那样用Javascript 进行编程。这意味着你可以用Javascript做很多事情,你不能用PHP做,不做修改。

答案 2 :(得分:1)

我闻到Adapter Pattern,甚至可能Decorator Pattern