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

问题描述 投票:0回答:7

好的我有下面的代码

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

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

php class function methods closures
7个回答
14
投票

您在 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();
}

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));
    }
}

你可以完成这项工作。这不太好。背景和示例位于我的一篇博客文章中:

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


4
投票

使用

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

这将显示“啊哈哈”

希望有帮助。


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


2
投票

自 PHP 7 起的新方法:

您可以将实例和方法放在圆括号中来调用该方法,如下所示:

($this->bar)();

这会导致早期版本出现语法错误。

如果有人参考了此更改的文档,请发表评论。


1
投票

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


0
投票

使用

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

© www.soinside.com 2019 - 2024. All rights reserved.