PHP Anonymous Functions: What Are They, and Why Use Them?

Learn how to create and use anonymous functions, callbacks and closures in PHP.

PHP Anonymous Functions: What Are They, and Why Use Them?

In this tutorial you'll explore anonymous functions in PHP. Anonymous functions are a PHP feature that you probably won't use that often; however, they can be really useful in certain situations, as you'll see.

You'll look at the following concepts in this tutorial:

  • What anonymous functions are, and how you create them
  • How to assign anonymous functions to variables
  • How to call anonymous functions
  • Using anonymous functions to create neater callbacks, and
  • Creating closures with anonymous functions.

Ready to dive into anonymous functions in PHP? Let's go!

Anonymous functions explained

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

Anonymous functions are similar to regular functions, in that they contain a block of code that is run when they are called. They can also accept arguments, and return values.

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

There are two subtle but important differences between the above example and a regular function definition:

  1. There is no function name between the function keyword and the opening parenthesis ('('). This tells PHP that you're creating an anonymous function.
  2. There is a semicolon after the function definition. This is because anonymous function definitions are expressions, whereas regular function definitions are code constructs.

While the above code is perfectly valid, it isn't very useful. Since the anonymous function has no name, you can't refer to it anywhere else in your code, so it can never be called!

However, since an anonymous function is an expression — much like a number or a string — you can do various handy things with it. For example, you can:

  • Assign it to a variable, then call it later using the variable's name. You can even store a bunch of different anonymous functions in a single array.
  • Pass it to another function that can then call it later. This is known as a callback.
  • Return it from within an outer function so that it can access the outer function's variables. This is known as a closure.

You'll explore these three techniques in the rest of this tutorial.

Assigning anonymous functions to variables

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]();

Using anonymous functions as callbacks

Megaphone

One common use of anonymous functions is to create simple inline callback functions. A callback function is a function that you create yourself, then pass to another function as an argument. Once it has access to your callback function, the receiving function can then call it whenever it needs to. This gives you an easy way to customise the behaviour of the receiving function.

Many built-in PHP functions accept callbacks, and you can also write your own callback-accepting functions. Let's look at a couple of built-in functions that use callbacks, and see how to use them.

Using array_map() to run a callback function on each element in an array

PHP's array_map() function accepts a callback function and an array as arguments. It then walks through the elements in the array. For each element, it calls your callback function with the element's value, and your callback function needs to return the new value to use for the element. array_map() then replaces the element's value with your callback's return value. Once it's done, array_map() returns the modified array.

array_map() works on a copy of the array you pass to it. The original array is untouched.

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

This approach saves a line of code, but more importantly, it avoids cluttering up the PHP file with a separate regular function that is only being used as a one-off callback.

Custom array sorting with usort()

Another common use of callbacks is with PHP's usort() function. This function lets you sort arrays using a sorting callback function that you write yourself. This is particularly handy if you need to sort an array of objects or associative arrays, since only you, as the coder, know the best way to sort such complex structures.

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

Creating closures with anonymous functions

Megaphone

Another common use of anonymous functions is to create closures. A closure is a function that retains access to the variables in its enclosing scope, even if that scope has since disappeared.

For example:

  1. A function, myFunction(), contains a local variable (or parameter) called $myVar.
  2. The function also defines and returns an anonymous function that accesses $myVar.
  3. Some other code calls myFunction() and gets back the anonymous function, which it stores in $anonFunction. By this time, myFunction() has, of course, finished running.
  4. If the code now calls $anonFunction(), the anonymous function can still access the $myVar local variable that was in myFunction(), even though myFunction() is no longer running! The anonymous function, together with its reference to the $myVar variable, constitute a closure.

Rather confusingly, the PHP manual refers to anonymous functions as closures. They are not the same thing! Anonymous functions are used to create closures.

Closures can be difficult to get your head around at first, but once you grasp the concept, they let you write clean, powerful and flexible code. Let's look at a couple of examples of closures to make things clearer.

A simple closure

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

Let's walk through this code:

  1. getGreetingFunction()
    getGreetingFunction() initialises a local variable, $timeOfDay, on line 5, and on lines 7-10 it also defines and returns an anonymous function (described below).
  2. The anonymous function
    On line 8, the anonymous function manipulates getGreetingFunction()'s local $timeOfDay variable by converting its first letter to uppercase, and on line 9 it returns a greeting string that contains $timeOfDay's value.

    • The use keyword
      Normally, the anonymous function wouldn't have access to the $timeOfDay variable, since that variable is local to getGreetingFunction()'s scope only. However, the use keyword on line 7 tells PHP to let the anonymous function access $timeOfDay. This lets us create the closure.
    • The ampersand
      The ampersand (&) before $timeOfDay tells PHP to pass a reference to the $timeOfDay variable into the anonymous function, rather than just copying the variable's value. This allows the anonymous function to manipulate $timeOfDay directly. Strictly speaking, a closure's function should always access variables in its enclosing scope by reference. That said, if you know that you won't need to change the value of a variable then you can omit the ampersand to pass the variable by value instead.
  3. Calling getGreetingFunction()
    On line 13, we call getGreetingFunction() and get back the returned anonymous function, which we store in a $greetingFunction variable.

    Note that, by this point, getGreetingFunction() has finished running. In normal circumstances, its local variable, $timeOfDay, would have fallen out of scope and disappeared. However, because we've created a closure using the anonymous function (now stored in $greetingFunction), the anonymous function can still access this $timeOfDay variable.
  4. Calling the anonymous function
    On line 14, we call our anonymous function. It manipulates the value of the $timeofDay variable inside the closure by converting its first letter to uppercase, then it returns a greeting containing $timeOfDay's new value, which is "Morning".

That, in a nutshell, is how you create a closure in PHP. It's a trivial example, but the important point to note is that the returned anonymous function can still access its enclosing function's $timeOfDay local variable, even after the enclosing function has finished running.

Using closures to pass additional data to callbacks

Now that we've seen how to create a closure, let's look at a common practical use for them.

When you pass a callback function to the PHP usort() function, and usort() calls your callback, the callback receives the two arguments passed to it by usort() — that is, the two values in the array to compare.

But what if you wanted your callback function to receive extra information? For example, taking our usort() example from earlier in the article, we might want to pass an additional $sortKey argument to our callback to tell it which key it should use for sorting the array ("name" or "age").

However, usort() — not us — calls our callback. Since it's called within usort()'s scope, we don't have a chance to pass additional arguments to the callback at the time it's called.

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

Let's walk through this code to see how it works:

  1. Create an array of people.
    First we create our usual array of people. Each person is represented by an associative array with two keys: "name" and "age".
  2. Define getSortFunction().
    Next we define a regular function, getSortFunction(), that accepts a $sortKey parameter. This is the key that we want our sorting callback function to use. Within getSortFunction(), we...
  3. Create the closure.
    On lines 8-10, getSortFunction() defines and returns an anonymous function, which is the sorting function that we'll pass to usort(). The anonymous function accepts the usual two array elements to sort — $personA and $personB — but it also uses the use keyword to access the $sortKey parameter, which is within the scope of the enclosing getSortFunction() function. This creates the closure. It then uses $sortKey to determine which key to use for the comparison (either "name" or "age").

    Remember: Since we've created a closure, the anonymous function still has access to the value of the $sortKey parameter after getSortFunction() has finished running.

  4. Sort the array.
    Finally our code sorts the array, first by name and then by age. To do this, it calls getSortFunction(), passing in the key to sort by ("name" or "age"). getSortFunction() then returns an appropriate anonymous sort function that uses the supplied sort key. The code then passes this anonymous function to usort(), along with the array to sort.
  5. You can use this trick any time you need to pass additional data to a callback function.

    Closures are quite a broad and subtle topic. If you're not familiar with them, check out the following good articles on anonymous functions and closures in PHP and closures and lambda functions, which explain in detail exactly what a closure is (and isn't).

    Summary

    In this tutorial you looked at anonymous functions in PHP, and saw how to use them in various situations. You learned:

    • That an anonymous function is much like a regular function, except it has no name, and is an expression rather than a code construct.
    • How to assign an anonymous function to a variable, and how to call the anonymous function using the variable.
    • Ways to use inline anonymous functions as callbacks to create neater, tidier code.
    • How to create closures using anonymous functions. Closures are useful for many things, including making code more readable, avoiding global variables, and creating customisable callback functions.

    I hope you found this tutorial helpful, and that you now feel confident creating and using anonymous functions in your PHP code. Have fun!

    [Image credits: Men, megaphone, gift boxes via Shutterstock]

    Learn PHP With Ease!

    Written by Matt Doyle — ELATED's resident Web programming expert — Beginning PHP 5.3 is a complete introduction to PHP, covering everything in these tutorials and lots more besides. Find out how to:

    • Set up PHP on your computer
    • Use strings, arrays, functions and objects
    • Create interactive Web forms
    • Handle cookies and sessions
    • Work with files on the server
    • Build database-driven sites with MySQL
    • Send emails from your scripts
    • Create images on the fly with PHP
    • Work with regular expressions
    • Write robust, secure PHP applications

    ...and lots more!

    “What a pleasure it's been spending hours and hours studying PHP with this magical book.” — Lulio, Florida
    “The book is not only great for learning, but I find myself using it constantly as a reference as well!” — David A. Stoltz

    Buy Beginning PHP 5.3 now from Amazon.comBeginning PHP 5.3 or Amazon.co.ukBeginning PHP 5.3.

    Follow Elated

    Related articles

    Responses to this article

    2 responses (oldest first):

    10-Dec-12 22:42
    Thanks for article...
    Some of it is a bit over my head, but I get the general gist!
    One thing that has me confused is the usort example.
    Should this line:
    return ( $personA["age"] < $personB["age"] ) ? -1 : 1;
    Have "name" for $personA ?
    Cheers, Dave
    11-Dec-12 13:39
    name??

    That line is the equvalent of



    <?php>
    if($A < $B) {
    return -1;
    } else {
    return 1;
    }
    ?>

    Post a response

    Want to add a comment, or ask a question about this article? Post a response.

    To post responses you need to be a member. Not a member yet? Signing up is free, easy and only takes a minute. Sign up now.

    Top of Page