Is it possible to reference an anonymous function from within itself in PHP?

Asked
Active3 hr before
Viewed126 times

9 Answers

functionanonymousreferencepossible
90%

How can we do it without having to name the anonymous function? – Pacerier Jul 13 '13 at 9:18 ,Connect and share knowledge within a single location that is structured and easy to search.,Thanks for contributing an answer to Stack Overflow!, Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers

Try doing

$func = function() use( /*your variables,*/ & $func) {
   var_dump($func);
   return 1;
};
load more v
88%

Anonymous functions are implemented using the Closure class. ,Example #2 Anonymous function variable assignment example,Example #6 Attempting to use $this inside a static anonymous function, Anonymous functions

Notice: Undefined variable: message in /example.php on line 6
NULL
string(5)
"hello"
string(5)
"hello"
string(5)
"hello"
string(5)
"world"
string(11)
"hello world"
string(11)
"hello world"
load more v
72%

Currently, the only way to allow an anonymous function to call itself is to assign it to a variable, and give the anonymous function a reference to itself using the use keyword.,It turns out that yes, it is possible for an anonymous function to call itself. There are a few methods of doing it, but only one makes very much sense.,A anonymous function, also called a closure, is declared inline and used by another section of code. They are defined this way:,So, back to the original question: can you use an anonymous function recursively?

Static functions are the norm in PHP scripts. If you define a function like this, it's static:

function myFunction($arg) {
   echo $arg;
}

myFunction('Hiya'); // prints "Hiya"
load more v
65%

Ways to use inline anonymous functions as callbacks to create neater, tidier code.,Using anonymous functions to create neater callbacks, and,Can I call anonymous function inside another anonymous function?,You can use this trick any time you need to pass additional data to a callback function.

As you probably know, you define a regular function in PHP like this:

function myFunctionName() {
   // (Your function code goes here)
}

When you define a function, you give it a name (myFunctionName in the above example). PHP then lets your code refer to this function using its name. For example, you can call your function like this:

myFunctionName();

The key difference — as their name implies — is that anonymous functions have no name. Here’s a code example that creates a simple anonymous function:

// Declare a basic anonymous function
// (not much use on its own!)
function($name, $timeOfDay) {
   return ("Good $timeOfDay, $name!");
};

When you define an anonymous function, you can then store it in a variable, just like any other value. Here’s an example:

// Assign an anonymous function to a variable
$makeGreeting = function($name, $timeOfDay) {
   return ("Good $timeOfDay, $name!");
};

Once you’ve done that, you can call the function using the variable’s name, just like you call a regular function:

// Call the anonymous function
echo $makeGreeting( "Fred", "morning" ) . "<br>";
echo $makeGreeting( "Mary", "afternoon" ) . "<br>";

This produces the output:

Good morning, Fred!
   Good afternoon, Mary!

You can even store several functions inside an array, like this:

// Store 3 anonymous functions in an array
$luckyDip = array(

   function() {
      echo "You got a bag of toffees!";
   },

   function() {
      echo "You got a toy car!";
   },

   function() {
      echo "You got some balloons!";
   }
);

Once you’ve done that, your code can decide which function to call at runtime. For example, it could call a function at random:

// Call a random function
$choice = rand(0, 2);
$luckyDip[$choice]();

Here’s how you might use array_map() with a regular callback function:

// Create a regular callback function...
function nameToGreeting($name) {
   return "Hello ".ucfirst($name).
   "!";
}

// ...then map the callback function to elements in an array.
$names = array("fred", "mary", "sally");
print_r(array_map(nameToGreeting, $names));

This code creates a regular function, nameToGreeting(), that takes a string, $name, uppercases the first letter, prepends "Hello ", and returns the result. Then, on line 8, the code passes this callback function to array_map(), along with an array of names to work with, and displays the result:

Array([0] => Hello Fred![1] => Hello Mary![2] => Hello Sally!)

While this code works, it’s a bit cumbersome to create a separate regular function just to act as a simple callback like this. Instead, we can create our callback as an inline anonymous function at the time we call array_map(), as follows:

// A neater way:
// Map an anonymous callback function to elements in an array.
print_r(array_map(function($name) {
   return "Hello ".ucfirst($name).
   "!";
}, $names));

Let’s create an array of associative arrays, where each associative array has a name key and an age key:

$people = array(
   array("name" => "Fred", "age" => 39),
   array("name" => "Sally", "age" => 23),
   array("name" => "Mary", "age" => 46)
);

Now, say we want to sort the array in ascending order of age. We can’t use the regular PHP array sorting functions, since these don’t know anything about the age key. Instead, we can call usort() and pass in an anonymous callback function that sorts the array by age, like this:

usort($people, function($personA, $personB) {
   return ($personA["age"] < $personB["age"]) ? -1 : 1;
});

print_r($people);

This produces the result we want:

Array(
   [0] => Array([name] => Sally[age] => 23)[1] => Array([name] => Fred[age] => 39)[2] => Array([name] => Mary[age] => 46)
)

We’ll start by creating a very simple closure using an anonymous function:

// A simple example of a closure

function getGreetingFunction() {

   $timeOfDay = "morning";

   return (function($name) use( & $timeOfDay) {
      $timeOfDay = ucfirst($timeOfDay);
      return ("Good $timeOfDay, $name!");
   });
};

$greetingFunction = getGreetingFunction();
echo $greetingFunction("Fred"); // Displays "Good Morning, Fred!"

Closures to the rescue! By returning our callback function from inside another function and creating a closure, we can get the outer function to accept $sortKey as a parameter, then pass $sortKey to the callback inside the closure. Here’s the complete code:

$people = array(
  array( "name" => "Fred", "age" => 39 ),
  array( "name" => "Sally", "age" => 23 ),
  array( "name" => "Mary", "age" => 46 )
);

function getSortFunction( $sortKey ) {
  return function( $personA, $personB ) use ( $sortKey ) {
    return ( $personA[$sortKey] < $personB[$sortKey] ) ? -1 : 1;
  };
}

echo "Sorted by name:<br><br>";
usort( $people, getSortFunction( "name" ) );
print_r( $people );
echo "<br>";

echo "Sorted by age:<br><br>";
usort( $people, getSortFunction( "age" ) );
print_r( $people );
echo "<br>";

This code displays the expected output:

Sorted by name:

   Array(
      [0] => Array([name] => Fred[age] => 39)[1] => Array([name] => Mary[age] => 46)[2] => Array([name] => Sally[age] => 23)
   )

Sorted by age:

   Array(
      [0] => Array([name] => Sally[age] => 23)[1] => Array([name] => Fred[age] => 39)[2] => Array([name] => Mary[age] => 46)
   )
load more v
75%

Anonymous functions (with support for closures) have been present since PHP 5.3 (2009).,Recursion, a feature that allows a function to call itself, is supported by the language, but most of the PHP code focus is on iteration.,PHP 5.4 added the ability to bind closures to an object’s scope and also improved support for callables such that they can be used interchangeably with anonymous functions in almost all cases.,Read about Anonymous functions

< ? php
$input = array(1, 2, 3, 4, 5, 6);

// Creates a new anonymous function and assigns it to a variable
$filter_even = function($item) {
   return ($item % 2) == 0;
};

// Built-in array_filter accepts both the data and the function
$output = array_filter($input, $filter_even);

// The function doesn't need to be assigned to a variable. This is valid too:
$output = array_filter($input, function($item) {
   return ($item % 2) == 0;
});

print_r($output);
load more v
40%

It is not possible to use $this from anonymous function before PHP 5.4.0,Don't always rely on PHP to pass objects by reference, when you are assigning a reference itself, the behavior is not the same as in most OO languages where the original pointer is modified.,Is this a good practice? Is there a better way to access $this inside an anonymous function using PHP 5.3?,Even more, you will be able to change what $this points to at runtime, for anonymus functions (closure rebinding):

on the anonymous functions page. But I have found I can make it work by assigning $this to a variable and passing the variable to a use statement at the function definition.

$CI = $this;
$callback = function() use($CI) {
   $CI - > public_method();
};
load more v
22%

Alternatively, you could just declare the function globally and reference it from inside itself:,I think PHP keeps track of anonymous functions by giving them generated IDs for names, so I feel like "this" could exist in theory to point at the current function...,Basically, if I'm in some anonymous function, is there a way I can reference the function itself with some kind of this-like construct?,Almost? I did forget that existed, but it doesn't "work" with anonymous functions because you just get {closure} back rather than something callable.

I believe in PHP 8 you can assign a function to a variable, and then import that same variable into the function. For example, this is how you could write a recursive fibbonacci function.

$fibbonacci = function(int $max, int $carry, int $prev) use($fibbonacci) {
   if ($prev >= $max) {
      return $max;
   }

   $next = $carry + $prev;
   return $fibbonacci($max, $next, $carry)
}

Alternatively, you could just declare the function globally and reference it from inside itself:

function fibbonacci(int $max, int $carry, int $prev) {
   if ($prev >= $max) {
      return $max;
   }

   $next = $carry + $prev;
   return fibbonacci($max, $next, $carry)
}
load more v
60%

Another essential concept in coding is functions, which allow you to store a piece of code that does a single task inside a defined block, and then call that code whenever you need it using a single short command — rather than having to type out the same code multiple times. In this article we'll explore fundamental concepts behind functions such as basic syntax, how to invoke and define them, scope, and parameters.,The top level outside all your functions is called the global scope. Values defined in the global scope are accessible from everywhere in the code.,Keep in mind that you can call a function from anywhere, even inside another function.  This is often used as a way to keep code tidy — if you have a big complex function, it is easier to understand if you break it down into several sub-functions:,Keeping parts of your code locked away in functions avoids such problems, and is considered the best practice.

let myText = 'I am a string';
let newString = myText.replace('string', 'sausage');
console.log(newString);
// the replace() string function takes a source string,
// and a target string and replaces the source string,
// with the target string, and returns the newly formed string
load more v
48%

Normal function definition: ,An anonymous function is a function that was declared without any named identifier to refer to it. As such, an anonymous function is usually not accessible after its initial creation. ,Anonymous function definition: ,The trailing parentheses initiate a call to the function and can contain arguments

function hello() {
   alert('Hello world');
}
hello();
load more v

Other "function-anonymous" queries related to "Is it possible to reference an anonymous function from within itself in PHP?"