110

In JavaScript, you can define anonymous functions that are executed immediately:

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

Can you do something like that in PHP?

Geoffrey
  • 5,407
  • 10
  • 43
  • 78
Emanuil Rusev
  • 34,563
  • 55
  • 137
  • 201
  • 2
    I don't have php 5.3 on my hands to try out, but how does `call_user_func(function(){/* stuff */})` do? – Jasper Aug 25 '10 at 20:19

9 Answers9

142

For versions prior to PHP 7, the only way to execute them immediately I can think of is

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

With current versions of PHP, you can just do

(function() { echo 'executed'; })();
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • 12
    Unless (or, until) [function call chaining](http://wiki.php.net/rfc/fcallfcall) gets introduced, this would be my suggestion as well. – salathe Aug 25 '10 at 18:15
  • 2
    @Gordon: php 5.4 still nothing ? – dynamic Oct 30 '12 at 21:03
  • @yes123 nope. still have to use `call_user_func` – Gordon Oct 30 '12 at 22:41
  • 2
    @BennettMcElwee let's put it this way: even if this performs somewhat slower than the define-assign-call alternative, the likelihood of this posing a significant bottleneck in your application is very low. when in doubt profile your app under real world conditions. – Gordon Jun 21 '13 at 05:44
  • Thanks @Gordon, that's what I thought. I got the impression that salathe and yes123 weren't happy with this method, and I wondered why. Seems perfectly fine to me. – Bennett McElwee Jun 21 '13 at 10:47
  • @Gordon, I think he's asking about significant performance penalties e.g. reflection. – Pacerier Mar 27 '15 at 07:51
  • @BennettMcElwee, HHVM or ZE? – Pacerier Mar 27 '15 at 07:51
  • @Pacerier Personally, I would write code to cover all common cases, so I'd be interested to know of performance problems with either VM. – Bennett McElwee Mar 29 '15 at 08:00
  • Gordon, I edited your answer for PHP7, hope you don't mind. Feel free to adjust. Oh, and thanks for your nice original tip! – Sz. Jan 31 '17 at 21:43
34

In PHP 7 is to do the same in javascript

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

    return 3;
})();

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

echo $gen->getReturn(), PHP_EOL;

The output is:

1
2
3
Wallace Vizerra
  • 3,382
  • 2
  • 28
  • 29
15

Well of course you can use call_user_func, but there's still another pretty simple alternative:

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

?>
Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • 1
    I want an immediately executing function, because the function I am defining is one which SHOULDN'T be called more than once in normal execution. The problem with defining a named function, run(), like you have, is that anyone else who sees the code may think that they can call run() too in some other part of the code. The immediately-executing function makes it clear that this code should not be run twice. – Daniel Howard Sep 18 '13 at 09:05
  • 3
    They cannot call `run` on your function in some other part of the code because there is no handle to your function existing after the line which immediately executes it. – Pacerier Sep 18 '13 at 13:31
  • He means he doesn't want anyone else calling a function like run on any other function at all. – km6zla Oct 24 '13 at 23:24
  • 3
    @DanielHoward The point of `run()` is to immediately execute the unnamed function passed to it. Same as `call_user_func()`, only no parameters are passed. – Cypher Feb 07 '14 at 23:02
  • @ogc-nick, He means he doesn't want anyone else executing his function twice. Read *"The immediately-executing function makes it clear that this code should not be run twice"*. – Pacerier Apr 03 '15 at 20:12
  • does this provide any benefit over `call_user_func(function() { echo "do something"; })` other than using the shorter word `run`? – Jordan Lev Aug 30 '15 at 19:16
  • 1
    @JordanLev, It has a simpler implementation (just one line: `$f();`) and might be faster if the engine you use does not optimize for the special case where `call_user_func` has only one function argument. This is because [`call_user_func`](http://php.net/call-user-func) supports passing multiple parameters and it's first argument supports either a string as an argument or a function. That said, if `call_user_func` is much readable, I'd not use `run` unless the code is located somewhere at the bottom of [the pyramind](http://blog.codinghorror.com/the-one-trillion-dollar-development-pyramid/). – Pacerier Sep 02 '15 at 08:30
  • @Pacerier - not sure I understand the "simpler implementation" part... isn't `$f` just in the utility function that `run` calls... so the calling code is calling `run(function() { whatever })` instead of `call_user_func(function() { whatever })` -- same exact thing, just a shorter function name. Your point about performance is spot-on though (and I love the pyramid analogy)... the reason I need this is actually for a lower-level framework that will support lots of other applications so perhaps in my case this makes sense. Thanks! – Jordan Lev Sep 02 '15 at 16:34
  • 1
    @JordanLev, "simpler implementation" refers to the comparison between the code *inside* the functions `run` and `call_user_func`. `call_user_func` has an inherent disadvantage when compared to `run` because `run` does only one thing, whereas `call_user_func` supports additional features in addition to doing what `run` does. You can try a quick loop test ([e.g.](http://stackoverflow.com/a/13667734/632951)) to see which is faster on your engine. – Pacerier Sep 03 '15 at 04:33
  • 1
    +1 for the solution - I was just about suggesting exactly the same. Actually, I implemented it this way in my code when I realized there's no way to function{}(). – dkellner Nov 16 '15 at 07:32
15

This is the simplest for PHP 7.0 or later.

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

It means create closure, then call it as function by following "()". Works just like JS thanks to uniform variable evaluation order.

https://3v4l.org/06EL3

miken32
  • 42,008
  • 16
  • 111
  • 154
Yasuo Ohgaki
  • 429
  • 4
  • 4
6
(new ReflectionFunction(function() {
 // body function
}))->invoke();
innermond
  • 121
  • 1
  • 6
3

Note, accepted answer is fine but it takes 1.41x as long (41% slower) than declaring a function and calling it in two lines.

[I know it's not really a new answer but I felt it was valuable to add this somewhere for visitors.]

Details:

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

Results:

$ php test8.php
test1_anonfunc_call took 0.0081379413604736s (1228812.0001172/s)
test2_anonfunc_call_user_func took 0.011472940444946s (871616.13432805/s)
Shovas
  • 215
  • 1
  • 9
  • 1
    5-year follow-up :-) In PHP v8.2, using microtime() for benchmarking 100000 iterations, those invocation methods now have identical execution time (~0.034s). – Colin Jul 25 '23 at 02:23
  • Good follow-up @colin. I haven't been doing much php these past few years so it's good to hear it's still going strong. – Shovas Jul 26 '23 at 16:01
0

This isn't a direct answer, but a workaround. Using PHP >= 7. Defining an anonymous class with a named method and constructing the class and calling the method right away.

$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.
  • What possible value could there be to doing this instead of defining an anonymous function? Sure it's possible to do, but why? – miken32 May 21 '21 at 16:20
  • 1
    @miken32 Because maybe you want to execute more complex stuff than returning 'neato'. Having a class construct (anonymous singleton pattern) that will run once will allow for much more 'neato' organisation of your code. Whoever downvoted this answer should seriously question if they're active in the right industry. This answer is not strictly the right one for this question, but it's definitely a solid alternative when more complexity is needed than just a single function. BTW, you can just write ```(new class(){function __construct(){echo 'neato';}});``` to fire up the class. – zmippie Jul 25 '21 at 06:33
  • @miken32 Thanks for the feedback! It can be even cooler when using variables to dynamically call methods on an anonymous class, such as: https://stackoverflow.com/questions/5451394/call-method-by-string – thecoolestname36 Oct 27 '21 at 02:30
-1

I tried it out this way, but it's more verbose than the top answer by using any operator (or function) that allows you to define the function first:

    $value = $hack == ($hack = function(){
            // just a hack way of executing an anonymous function
            return array(0, 1, 2, 3);                
    }) ? $hack() : $hack();
Paul Jerome Bordallo
  • 1,362
  • 10
  • 11
-2

Not executed inmediately, but close to ;)

<?php

$var = (function(){ echo 'do something'; });
$var();

?>
James
  • 1
  • 1