【问题标题】:How do I immediately execute an anonymous function in PHP?如何在 PHP 中立即执行匿名函数?
【发布时间】:2010-08-25 16:58:53
【问题描述】:

在 JavaScript 中,您可以定义立即执行的匿名函数:

(function () { /* do something */ })()

你能在 PHP 中做类似的事情吗?

【问题讨论】:

  • 我手头没有php 5.3可以试用,但是call_user_func(function(){/* stuff */})怎么办?

标签: php javascript function


【解决方案1】:

对于 PHP 7 之前的版本,我能想到的立即执行它们的唯一方法是

call_user_func(function() { echo 'executed'; });

使用当前版本的 PHP,您可以这样做

(function() { echo 'executed'; })();

【讨论】:

  • 除非(或,直到)function call chaining 被介绍,这也是我的建议。
  • @Gordon: php 5.4 还是什么都没有?
  • @yes123 不。还是得用call_user_func
  • @BennettMcElwee 让我们这样说吧:即使它的执行速度比 define-assign-call 替代方案要慢一些,这在您的应用程序中造成重大瓶颈的可能性也非常低。如有疑问,请在真实条件下分析您的应用。
  • 谢谢@Gordon,我就是这么想的。我的印象是salathe 和yes123 对这种方法不满意,我想知道为什么。对我来说似乎很好。
【解决方案2】:

PHP 7 是在 javascript 中做同样的事情

$gen = (function() {
    yield 1;
    yield 2;

    return 3;
})();

foreach ($gen as $val) {
    echo $val, PHP_EOL;
}

echo $gen->getReturn(), PHP_EOL;

输出是:

1
2
3

【讨论】:

    【解决方案3】:

    当然你可以使用call_user_func,但还有另一个非常简单的替代方案:

    <?php
    // we simply need to write a simple function called run:
    function run($f){
        $f();
    }
    
    // and then we can use it like this:
    run(function(){
        echo "do something";
    });
    
    ?>
    

    【讨论】:

    • 我想要一个立即执行的函数,因为我定义的函数在正常执行中不应被多次调用。像您一样定义命名函数 run() 的问题在于,任何其他看到代码的人都可能认为他们也可以在代码的其他部分调用 run()。立即执行函数清楚地表明这段代码不应运行两次。
    • 他们不能在代码的其他部分调用你的函数的run,因为在立即执行它的行之后没有你的函数的句柄。
    • @DanielHoward run() 的重点是立即执行传递给它的未命名函数。同call_user_func(),只是不传参数。
    • @JordanLev,它有一个更简单的实现(只有一行:$f();),如果您使用的引擎没有针对call_user_func 只有一个函数参数的特殊情况进行优化,它可能会更快.这是因为call_user_func 支持传递多个参数,并且它的第一个参数支持字符串作为参数或函数。也就是说,如果call_user_func 可读性强,我不会使用run,除非代码位于the pyramind 底部的某处。
    • @JordanLev,“更简单的实现”是指代码内部函数runcall_user_func之间的比较。与run 相比,call_user_func 有一个固有的劣势,因为run 只做一件事,而call_user_func 除了做run 所做的事情之外还支持其他功能。您可以尝试快速循环测试 (e.g.),看看哪个引擎更快。
    【解决方案4】:

    这对于 PHP 7.0 或更高版本是最简单的。

    (function() {echo 'Hi';})();
    

    这意味着创建闭包,然后通过“()”将其作为函数调用。得益于统一的变量评估顺序,可以像 JS 一样工作。

    https://3v4l.org/06EL3

    【讨论】:

    • 很好的答案,但是为什么要格式化为命令行操作呢?
    【解决方案5】:
    (new ReflectionFunction(function() {
     // body function
    }))->invoke();
    

    【讨论】:

    • 你能提供更多细节吗?也许添加一个解释?
    【解决方案6】:

    注意,accepted answer 很好,但它比声明一个函数并在两行中​​调用它需要 1.41 倍(慢 41%)。

    [我知道这并不是一个真正的新答案,但我觉得将其添加到访问者的某个地方很有价值。]

    详情:

    <?php
    # Tags: benchmark, call_user_func, anonymous function 
    require_once("Benchmark.php");
    bench(array(
            'test1_anonfunc_call' => function(){
                    $f = function(){
                            $x = 123;
                    };
                    $f();
            },
            'test2_anonfunc_call_user_func' => function(){
                    call_user_func(
                            function(){
                                    $x = 123;
                            }
                    );
            }
    ), 10000);
    ?>
    

    结果:

    $ php test8.php
    test1_anonfunc_call took 0.0081379413604736s (1228812.0001172/s)
    test2_anonfunc_call_user_func took 0.011472940444946s (871616.13432805/s)
    

    【讨论】:

      【解决方案7】:

      这不是直接的答案,而是一种解决方法。使用 PHP >= 7. 使用命名方法定义匿名类并构造类并立即调用该方法。

      $var = (new class() { // Anonymous class
          function cool() { // Named method
              return 'neato';
          }
      })->cool(); // Instantiate the anonymous class and call the named method
      echo $var; // Echos neato to console.
      

      【讨论】:

      • 这样做而不是定义匿名函数有什么可能的价值?当然可以,但为什么呢?
      • @miken32 因为也许你想执行比返回 'neato' 更复杂的东西。拥有一个运行一次的类构造(匿名单例模式)将允许您的代码更加“整齐”地组织。否决这个答案的人应该认真质疑他们是否活跃在正确的行业中。这个答案严格来说并不是这个问题的正确答案,但当需要比单个函数更复杂时,它绝对是一个可靠的选择。顺便说一句,你可以写(new class(){function __construct(){echo 'neato';}}); 来启动课程。
      • @miken32 感谢您的反馈!使用变量动态调用匿名类上的方法会更酷,比如:stackoverflow.com/questions/5451394/call-method-by-string
      【解决方案8】:

      我尝试过这种方式,但通过使用允许您首先定义函数的任何运算符(或函数),它比最佳答案更冗长:

          $value = $hack == ($hack = function(){
                  // just a hack way of executing an anonymous function
                  return array(0, 1, 2, 3);                
          }) ? $hack() : $hack();
      

      【讨论】:

      • 那为什么不干脆$hack = function(){...}; $hack()呢?
      【解决方案9】:

      不立即执行,但接近;)

      <?php
      
      $var = (function(){ echo 'do something'; });
      $var();
      
      ?>
      

      【讨论】:

        猜你喜欢
        • 2016-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-16
        • 1970-01-01
        • 1970-01-01
        • 2021-08-11
        相关资源
        最近更新 更多