3

好的,我确实有下面的代码

<?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

这可能吗?我是不是做错了什么?请纠正我

4

6 回答 6

12

您在 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();
}
于 2012-08-30T12:10:15.900 回答
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));
    }
}

你可以完成这项工作。这不是很好。背景和示例在我的一篇博文中:

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

于 2012-08-30T12:14:47.690 回答
2

你将无法做到这一点。

以这段代码为例:

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将按预期打印。

于 2012-08-30T12:11:34.870 回答
2

使用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();

这将显示“啊哈”

希望能帮助到你。

于 2012-08-30T12:15:04.593 回答
1

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

于 2012-08-30T12:10:37.460 回答
0

用于__call捕获所有未定义的方法,然后查找闭包并调用它。看看我在这个SitePoint 线程上的帖子。

于 2012-08-30T12:13:01.310 回答