Executing anonymous functions immediately in PHP

By Joel Stein on December 13, 2012

In PHP 5.3, anonymous functions (or “closures”) were introduced. To those who know Javascript well, these will be familiar. They allow you to create a sort of one-off function, and they’re all sorts of useful.

For example, when sorting multi-dimensional arrays, you almost always need a separate function to compare your values. Who wants to create a function just to perform this one-off task? Where do you put it? What do you name it so it doesn’t conflict with other sorting function names? Should you build some complicated super-function that handles all your varied sorting needs? No, just make an anonymous function, like this:

// These posts are currently sorted by date descending.
$posts[] = array('date' => 'tomorrow', 'title' => 'World');
$posts[] = array('date' => 'today', 'title' => 'Hello');

// Let's post them by date ascending.
usort($posts, function($a, $b) {
  return strtotime($a['date']) < strtotime($b['date']);
});

There, all done, nice and tidy. The anonymous function returned a reference, and that reference served as a callback in usort.

Now, let’s say you want to perform a one-off task where you need to create some temporary variables, but you don’t want to run the risk of having variable naming conflicts farther down the script. Wouldn’t it be nice if you could just create a quick anonymous function that executes immediately? Unfortunately, I don’t think it’s possible to chain the definition of the callback to it’s immediate execution, like you can in Javascript:

(function() {
  alert('Hello.');
})()

However, since an anonymous function in PHP returns a reference to itself, you can just stuff it inside call_user_func, which executes immediately. So, it sort of looks like Javascript. Sort of.

// Note the title.
$title = 'Great title';
$posts[] = array('date' => 'tomorrow', 'title' => 'World');
$posts[] = array('date' => 'today', 'title' => 'Hello');

// Convert post titles to lowercase.
call_user_func(function() use (&$posts) {
  foreach ($posts as &$post) {
    $title = strtolower($post['title']);
    $post['title'] = $title; // I know, this is a silly example.
  }
});

echo $title; // Will result in 'Great Title'.

Handy! An anonymous function, right where we need it (and nowhere else), executed immediately.

To learn more about anonymous functions, how to pass parameters to them, or what the “use” keyword does (which is also quite use-ful), read the documentation about anonymous functions, and this helpful explanation.

UPDATE (4/27/13): You can even have your anonymous function execute recursively. First, you assign it to a variable, and pass that variable by reference to the function. Now, that variable name can be executed within the anonymous function.

For example, say you wanted to convert all values in an array to their uppercase values (yes, this can be done another way). Here’s how you could do this in a recursive anonymous function.

$upper = function($string) use (&$upper) {
  return is_array($string) ? array_map($upper, $string) : strtoupper($string);
};
array_map($upper, array('joel', 'stein', array('steindom.com', 'random.pw')));