在PHP中的类属性中存储闭包函数

时间:2012-08-30 12:02:21

标签: php class function methods closures

好的,我确实有以下代码

<?php
    class foo{
       public $bar = NULL;

       public function boo(){
          $this->bar();
       }
    }

    $mee = new foo();

    //save a closure function on the property
    $mee->bar = function(){
        echo 'hahaha';
    };

    //invoke the closure function by using a class method
    $mee->boo();
?>

你可以看到它在这里运行http://codepad.org/s1jhi7cv

现在我想要的是将闭包函数存储在类方法上。

我可以在http://php.net/manual/en/functions.anonymous.php

阅读有关它的文档时关闭井 这可能吗?我做错了吗?请纠正我

6 个答案:

答案 0 :(得分:11)

您在codepad.org上的示例代码不起作用,因为codepad.org使用PHP 5.2.5,并且仅在5.3中添加了闭包支持。

但是,您的代码也无法在支持闭包的PHP版本中运行,但您会收到不同的错误:http://codepad.viper-7.com/Ob0bH5

目前这是PHP的限制。 $obj->member()查找名为member的方法,不会查看属性以查看它们是否可调用。坦率地说,这很烦人。

我知道在没有call_user_func() / call_user_func_array()的情况下开展这项工作的唯一方法是:

public function boo() {
   $func = $this->bar;
   $func();
}

答案 1 :(得分:4)

你需要利用PHP的一些神奇功能(__call)来利用它。例如,从Extendable扩展:

class Extendable {
    static function import($context) {
        $self = new static();
        while (is_callable($context)) $context = $context($self);
        if (is_array($context) || is_object($context) || is_a($context, 'Traversable')) {
            foreach($context as $key => $value)
                $self->$key = &$value; # preserve keys if
        }
        return $self;
    }
    public function __call($name, $args) {
        if (isset($this->$name) && is_callable($this->$name)) {
            return call_user_func_array($this->$name, $args);
        }
        throw new BadFunctionCallException(sprintf('Undefined function %s.', $name));
    }
}

你可以做这个工作。这不是那么好。背景和示例在我的一篇博文中:

你也可以自然地实现你自己的神奇功能。

答案 2 :(得分:1)

PHP不是基于原型的语言,因此您无法重新定义函数

答案 3 :(得分:1)

你将无法做到这一点。

以此代码为例:

class T {
  function foo() {
    echo 'T::foo';
  }
}

$t = new T;
$t->foo = function() {
  echo 'Closure::foo';
};
$t->foo();

它在PHP 5.4.6和/或PHP 5.3.16上运行良好,但它会导致T::foo被打印。

这是因为PHP中的方法不是可修改的类属性,例如在javascript中。

然而,

$foo = $t->foo;
$foo();

将按预期打印Closure::foo

答案 4 :(得分:1)

使用__call捕获所有未定义的方法,然后查找闭包并调用它。看一下我SitePoint thread上的帖子。

答案 5 :(得分:1)

使用call_user_func()功能:

<?php
    class foo{
       public $bar = NULL;

       public function boo(){
          call_user_func($this->bar);
       }
    }

    $mee = new foo();

    //save a closure function on the property
    $mee->bar = function(){
        echo 'hahaha';
    };

    //invoke the closure function by using a class method
    $mee->boo();

这将显示“ahahah”

希望它有所帮助。