繁体   English   中英

php在实例中设置匿名函数

[英]php Set a anonymous function in an instance

我刚刚开始使用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

您可以使用__call magic函数执行此作业。 不是美女,但它有效..

像这样:

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

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的主干 ,并且补丁引发了关于函数调用链的讨论,其语法可能允许你在没有__call hack的情况下尝试做什么。 不幸的是, 过去很难让函数调用链工作。

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

听起来你正在描述一个策略模式装饰模式 - 还有其他 方法可以实现这一点,这种方式更容易与阅读代码的其他开发人员进行沟通。

你可以沿着这些方向做一些事情(这也适用于不是闭包的回调):

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

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

这不再是PHP 7的问题;

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

查看有关AST的更多信息

您可以使用call_user_func直接执行callable,而不是将__call魔术方法挂钩到您的类中。

class A {
    public $b;
}

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

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

显然,PHP提供一些直接执行它的语法会很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM