PHP: anonymous functions, lambdas and closures

Three months ago I wrote post about arrow functions in JavaScript. It’s very nice feature, that can help write code faster and also solves “this” keyword range and visibility. This method is available in JavaScript and several other languages. But what about PHP? Unfortunatelly, we can’t use arrow functions in this language, they aren’t supported now (November 2018), there is only a RFC and experimental implementantion. Maybe in next versions… But we can also use anonymous functions, we can also use closures and lambdas. This post is about them.

What is anonymous function in PHP? As a name suggests, it’s a function without name. We can create at any time, but it may be useless. Let’s look on simple example of anonymous function, which doing hard work, but can  never been called, because hasn’t name to do this:

function () {
   // some hard work
   // more hard work!
}

echo 'Hello world!'
// we can't use function - how to call it?

 Useless? Yes. But you can also set anonymous function as variable and use it then as… this variable. See other example:

$hardWork = function () {
   // a lot of hard work
}

echo 'Hello world';
$hardWork(); // yes!

It’s now fully usable and we can use this in many ways. This constrution called “lambda” and we can use it in other functions. Yes, you can pass such variable (function) to other function as a parameter. You can also write function directly when you call parent function. Here is an example how to do this:

$hardWork = function () {
   // a lot of hard work
}

function workHarder($work) {
   $result = $work()
   echo $result;
}

// Pass function to function as variable
workHarder($hardWork);

// Pass anonymous function
workHarder(function () {
   // make some hard work
   // this result will be displayed in "echo $result" in hard work
   return $work; 
});

This construction is particularly useful on every callbacks-based functions. For example arrays manipulators like array_map, array_filter or array_walk. There is an example of using “tradicional” method and also anonymous function on calling array_walk:

$arr = ['One', 'Two', 'Three'];

// Standard method
function displayElement($element) {
   echo 'Element: ' . $element;
}

// Standard call
array_walk($arr, 'displayElement');

// Call using anoinymous function with the same result
array_walk($arr, function ($element) {
   echo 'Element: ' . $element;
});

As you can see, anonymous function are much shorter in this case – but it’ isn’t repeatable in contrast to standard function. You should use them in specific situations, only when you don’t have to repeat the same code in many places – in such case, standard function (or method) is much better option.

The last thing are closures. Sometimes we must use additional variables inside callbacks, not only for example array elements, but also external data. How can we do that? Variables are limited by scopes, but there are two solutions: first is to pass array with object and method as callback, and then, inject some data to object, but it’s complicated and “dirty”. Second is to use closues – anonymous function with “use ($variables)” construction. Let’s look on example, it’s the best way to explain this:

$number = 5;
$arr = [1,2,3,4,5,6,7,8,9];

// With use $number will be available inside anonynous function
array_walk($arr, function ($element) use ($number) {
   echo $number * $element;
});

With use, you can pass additional data to anonymous function. Of course, you can pass more arguments . Conculusion: anonymous functions are very nice feature and with them, all arrays functions are much more useful and cleaner.