PHP Anonymous Functions

Summary: in this tutorial, you will learn about PHP anonymous functions and how to use them effectively.

Introduction to anonymous functions

When you define a function, you specify a name for it. Later, you can call the function by the name.

For example, to define a function that multiplies two numbers, you can do it as follows:

<?php function multiply($x, $y) { return $x * $y; }
Code language: HTML, XML (xml)

The multiply() function accepts two arguments and returns the result. To call the multiply() function, you pass the arguments to it like this:

<?php multiply(10, 20);
Code language: HTML, XML (xml)

In this example, the multiply() is a named function. And you can reuse it as many times as you want.

Besides named functions, PHP allows you to define anonymous functions.

An anonymous function is a function that doesn’t have a name.

The following example defines an anonymous function that multiplies two numbers:

<?php function ($x, $y) { return $x * $y; };
Code language: HTML, XML (xml)

Since the function doesn’t have a name, you need to end it with a semicolon (;) because PHP treats it as an expression.

This anonymous function is not useful at all because you cannot use it like a named function.

To use an anonymous function, you need assign it to a variable and call the function via the variable.

The following example assigns the anonymous function to the $multiply variable:

<?php // ... $multiply = function ($x, $y) { return $x * $y; };
Code language: HTML, XML (xml)

And this calls the anonymous function via the $multiply variable:

echo $multiply(10, 20);
Code language: PHP (php)

When you dump the information of the $multiply variable, you’ll see that it’s actually a Clousure object:

object(Closure)#1 (1) { ["parameter"]=> array(2) { ["$x"]=>string(10) "<required>" ["$y"]=>string(10) "<required>" } }
Code language: PHP (php)

Note that the Closure in PHP is not the same as the closure in other programming languages such as JavaScript or Python.

Since an anonymous function is an object, you can assign it to a variable, pass it to a function, and return it from a function.

Passing an anonymous function to another function

PHP has many built-in functions that accept a callback function, for example, the array_map() function.

The array_map() function accepts a callback function and an array. It applies the callback function to each element and includes the results in a new array.

The following example shows how to double each number in an array:

<?php function double_it($element) { return $element * 2; } $list = [10, 20, 30]; $double_list = array_map(double_it, $list); print_r($double_list);
Code language: HTML, XML (xml)

How it works.

  • First, define a named function called double_it to double a number.
  • Second, define an array of integers.
  • Third, call the array_map() function to double each element of the $list array.
  • Finally, show the result array.

Output:

Array ( [0] => 20 [1] => 40 [2] => 60 )
Code language: PHP (php)

This example works perfectly fine. However, it’s quite verbose. And the double_it function may be used once.

The following example does the same but use an anonymous function instead:

<?php $list = [10, 20, 30]; $results = array_map(function ($element) { return $element * 2; }, $list); print_r($results);
Code language: HTML, XML (xml)

Scope of the anonymous function

By default, an anonymous function cannot access the variables from its parent scope. For example:

<?php $message = 'Hi'; $say = function () { echo $message; }; $say();
Code language: HTML, XML (xml)

PHP issued the following notice:

PHP Notice: Undefined variable: message in ...
Code language: plaintext (plaintext)

In this example, the anonymous function attempts to access the $message variable from its parent scope. However, it could not. Therefore, PHP issued a notice.

To use the variables from the parent scope inside an anonymous function, you place the variables in the use construct as follows:

<?php $message = 'Hi'; $say = function () use ($message) { echo $message; }; $say();
Code language: HTML, XML (xml)

Now, it should work correctly.

Note that the $message is passed to the anonymous function by value, not by reference. If you change it inside the anonymous function, the change will not reflect outside of the function. For example:

<?php $message = 'Hi'; $say = function () use ($message) { $message = 'Hello'; echo $message; }; $say(); echo $message;
Code language: HTML, XML (xml)

In this example, inside the anonymous function the value of the $message is 'Hello'. However, outside of the anonymous function, the value of the message remains the same as 'Hi'.

If you want to pass a variable to an anonymous function by reference, you need to use the & operator like the following example:

<?php $message = 'Hi'; $say = function () use ($message) { $message = 'Hello'; echo $message; }; $say(); echo $message;
Code language: HTML, XML (xml)

Now, you see the 'Hello' messages twice.

Return an anonymous function from a function

The following example illustrates how to return an anonymous function from a function:

<?php function multiplier($x) { return function ($y) use ($x) { return $x * $y; }; } $double = multiplier(2); echo $double(100); // 200 $tripple = multiplier(3); echo $tripple(100); // 300
Code language: HTML, XML (xml)

How it works.

  • First, define a function called mutiplier that returns an anonymous function.
  • Second, call the multiplier function and assign its returned value to the $double variable. Since the return value is a function, it can be invoked like a regular function ($double(2)).
  • Third, call the multiplier function and assign its returned value to the $tripple variable. This time we passed 3 instead of 2.

Summary

  • An anonymous function is a function without a name.
  • An anonymous function is a Closure object.
  • To access the variables from the parent scope inside an anonymous function, place the variables in the use construct.
  • An anonymous function can be assigned to a variable, passed to a function, or returned from a function.
Did you find this tutorial useful?