35

I have an anonymous function which is supposed to call itself. However, I have no variable or function name at hand, so I was hoping to find a function that could do return "this" in context of functions. Is there such a thing?

Here's an example:

$f = function() use($bar, $foo) {
  // call this function again.
};

Calling like this:

call_user_func(__FUNCTION__);

Leads to this:

Warning: call_user_func() expects parameter 1 to be a valid callback, function '{closure}' not found or invalid function name

If I try to put $f in the use-list, then it says the variable is not defined (because it is not yet).

Esailija
  • 138,174
  • 23
  • 272
  • 326
Tower
  • 98,741
  • 129
  • 357
  • 507
  • 2
    stop downvoting the answers, your original question didn't mention anonymous function anywhere. You should give them time to edit or delete. – Esailija Nov 29 '11 at 13:04
  • See http://stackoverflow.com/questions/2480179/anonymous-recursive-php-functions – Paul Dixon Nov 29 '11 at 13:04
  • @Esailija I'm not down voting anything. I wish there was a way to see the down voters. – Tower Nov 29 '11 at 13:05
  • __FUNCTION__(); See http://php.net/manual/en/language.constants.predefined.php. –  Nov 29 '11 at 12:59

5 Answers5

76

__FUNCTION__ cannot be used in anonymous functions

Pass the variable holding the anonymous function as a reference in the 'use' clause....

$f = function() use($bar, $foo, &$f) {
   $f();
};

Tip of the hat to this answer.

Community
  • 1
  • 1
Paul Dixon
  • 295,876
  • 54
  • 310
  • 348
8

Okay, I found out the way to do this:

$f = function() use(&$f) {
  $f();
};

$f();

The key thing is to pass $f as a reference. Thus PHP does not try to pass a value but a reference to a memory slot.

Tower
  • 98,741
  • 129
  • 357
  • 507
0

I have an anonymous function which is supposed to call itself.

I prefer to use call_user_func_array(__FUNCTION__, $params); when calling a recursive function.

As your example doesn't have any arguments then i guess call_user_func(__FUNCTION__); would be better suited.

You would expect and hope the following code would work but that would be too easy.

$bar = 10;
$foo = 0;

$f = function() use (&$bar,$foo) {

    if($bar){ // condition needed to prevent infinite loop
        echo $bar-- . PHP_EOL;
        call_user_func(__FUNCTION__); // wont work
    }
};
$f();

The __FUNCTION__ "Magic constant" is unavailable to closures so the code needs to be adapted to allow the passing of the function variable. we can make the function available by passing it as a regular argument or via the use statement.

Function passed as argument

$bar = 10;
$foo = 0;

$f = function( $__FUNCTION__ = null ) use (&$bar, $foo) {

    if($__FUNCTION__ && $bar){
        echo $bar-- . PHP_EOL;
        call_user_func( $__FUNCTION__, $__FUNCTION__);
    }
};
$f ( $f );

Function passed via use statement

$bar = 10;
$foo = 0;

$__FUNCTION__ = function() use (&$bar, $foo, &$__FUNCTION__) {

    if($bar){
        echo $bar-- . PHP_EOL;
        call_user_func( $__FUNCTION__ );
    }
};
$__FUNCTION__();

Working example, click edit-> ideone it! to re-run code.

TarranJones
  • 4,084
  • 2
  • 38
  • 55
-1

http://www.php.net/manual/en/language.constants.predefined.php

Edit: Posted before code was given. Of course it doesn't work on anonymous functions.

call_user_func(__FUNCTION__, $param1, $param2);
call_user_func_array(__FUNCTION__, $params);
Nameless
  • 2,306
  • 4
  • 23
  • 28
  • 1
    Warning: call_user_func() expects parameter 1 to be a valid callback, function '{closure}' not found or invalid function name – Tower Nov 29 '11 at 13:04
-4
function i_dont_know() {
    call_user_func(__FUNCTION__,$params);
 //or
    $funcname = __FUNCTION__;
    $funcname($params);


}
Lylo
  • 1,221
  • 1
  • 9
  • 12