7

我刚开始使用 PHP,我想知道是否有一种方法可以将匿名函数添加到类实例中。

例如,让我们说...

class A{
    public B;
}

$c = new A();

//This is where I am getting a little confused...
//The following wont work

$c->B = function(){echo('HelloWorld');};
$c->B();

我希望做的是在大量不同的应用程序中重用相同的代码,并使其能够在特定情况下“换出”并替换功能。

我正在使用 php5.3(所以匿名函数应该可以工作,只是不是以我使用它们的方式)。

非常感谢您的宝贵时间!!

-GK

4

7 回答 7

10

您可以使用__call魔术函数来完成这项工作。不是美女,但它有效..

像这样:

class A {
    public $B;

    public function __call($closure, $args)
    {
        call_user_func_array($this->$closure, $args);
    }
}

$c = new A();

$c->B = function () { echo('HelloWorld'); };
$c->B();
于 2010-06-13T22:17:08.743 回答
5

FWIW:

PHP 5.3 对匿名函数的处理很有趣。这不起作用:

$c->B = function() { echo func_get_arg(0); };
$c->B("This fails :(");

这将起作用:

$c->B = function() { echo func_get_arg(0); };
$hilarious = $c->B;
$hilarious("This works!");

要解决这个问题,您需要使用像Oden 提供的__call那样的 hack 。

这种行为将来可能会改变。数组取消引用 RFC最近被提交到 PHP 的 trunk,并且该补丁引发了关于函数调用链接的讨论,其语法可能允许您在没有 __call hack 的情况下尝试做的事情。不幸的是,过去证明很难让函数调用链正常工作。

于 2010-06-14T00:24:12.947 回答
4
# real ugly, but PoC...

class a {
  function __call($f, $x) {
    call_user_func_array($this->$f, $x);
  }
}

$a = new a;
$a->b = function() { echo "Hello world"; };
$a->b();
于 2010-06-13T22:16:32.430 回答
2

听起来您正在描述一种策略模式装饰器模式——还有其他 方法可以更容易地与阅读您的代码的其他开发人员交流。

于 2010-06-13T22:11:15.990 回答
1

您可以按照以下方式做一些事情(这也适用于不是闭包的回调):

<?php
class A {
    private $fun;
    function setFun($fun) {
        if (!is_callable($fun))
            throw new InvalidArgumentException();
         $this->fun = $fun;
    }
    public function fun() {
        call_user_func_array($this->fun, func_get_args());
    }
}

$c = new A();

$c->setFun(function($a) { echo('HelloWorld ' . $a);});
$c->fun("here");

这给出了HelloWorld here.

也就是说,您还应该考虑继承或装饰器模式

于 2010-06-13T22:10:02.883 回答
1

PHP 7 不再是这个问题;

// no error
$result = ($this->anonFunc)();
$result = ($this->anonFunc)($arg1, $arg2, ...);

查看更多关于AST的信息。

于 2016-03-09T00:22:53.873 回答
0

与其将 __call 魔术方法挂钩到您的类中,不如直接使用call_user_func.

class A {
    public $b;
}

$c = new A();
$c->b = function(){echo('HelloWorld');};

call_user_func($c->b);    // HelloWorld

显然,PHP 最好提供一些语法来直接执行它。

于 2014-03-04T12:14:13.083 回答