【问题标题】:php Set a anonymous function in an instancephp 在实例中设置匿名函数
【发布时间】:2011-03-03 07:42:30
【问题描述】:

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

【问题讨论】:

  • 您能详细介绍一下您尝试实现的这些不同的应用程序吗?我认为简单的继承可能是更好的解决方案,但更多信息会有所帮助。
  • GK 在这里,@Tim Cooper 我正在为我正在开发的游戏在服务器端工作,服务器将由数十个应用程序组成,这些应用程序将管理不同的部分的游戏。它们都将非常相似,并且使用许多相同的类,但是它们都需要能够执行自定义函数...摘要我知道,...感谢您的帮助! @dev-null-dweller 我认为你是对的,我尝试先查找此问题,但显然我看起来不够努力,谢谢!!

标签: php class instance anonymous-function


【解决方案1】:

您可以使用__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();

【讨论】:

  • gk 在这里,我会调查一下...我需要弄清楚是什么...非常感谢您为我指明正确的方向!
  • 已编辑以恢复反对票。我看到你发布了与 user358390 完全相同的解决方案(减去微小的差异),但我没有注意到时间如此接近,所以我给出了怀疑的好处
【解决方案2】:

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!");

要解决此问题,您需要使用__call hack,例如provided by Oden

这种行为可能在未来发生变化。 array dereferencing RFCrecently committed to PHP's trunk,该补丁引发了对 function call chaining 的讨论,其语法可能允许您在没有 __call hack 的情况下进行操作。不幸的是 proven difficult in the past 让函数调用链正常工作。

【讨论】:

  • 只使用搞笑的方法有什么问题?
【解决方案3】:
# 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();

【讨论】:

    【解决方案4】:

    听起来您在描述Strategy PatternDecorator Pattern - 有other ways 以更容易与阅读您的代码的其他开发人员交流的方式实现这一目标。

    【讨论】:

      【解决方案5】:

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

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

      也就是说,您还应该考虑继承或decorator pattern

      【讨论】:

        【解决方案6】:

        这在 PHP 7 中不再是问题;

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

        查看更多关于AST的信息。

        【讨论】:

          【解决方案7】:

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

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

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

          【讨论】:

            猜你喜欢
            • 2014-09-11
            • 2015-10-10
            • 1970-01-01
            • 2015-01-27
            • 2014-08-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-12
            相关资源
            最近更新 更多