Skip to content
Theory · Functions as values · lesson 1 of 8

Anonymous functions and callables

What you'll learn

What you'll learn:

  • store a function in a variable and pass it to another function through a callable parameter;
  • capture outer variables with use and tell a copy of the value from use (&$x);
  • write short arrow functions with fn and make a closure from an existing function with strlen(...);
  • sort an array by your own rule with usort and the <=> operator.
A recipe card fn with a jar clipped on as use slides along a counter to a chef's hat usort

In the first theme, a function was a recipe card: the main recipe pointed to the cream card, the cook followed it and came back with the result. Such a card stays in its place, and you call it by name.

Now picture a card you can pick up and hand to someone else. The pastry chef does not know in advance which filling you want. You hand them the recipe card, and they cook from it.

PHP lets you treat a function the same way: put it in a variable, pass it to another function and call it there. Let's start with a function in a variable:

PHP
<?php

$double = function (int $n): int {
    return $n * 2;
};

echo $double(4), "\n"; // 8
echo $double(10), "\n"; // 20
echo gettype($double), "\n"; // object

Let's walk through the program line by line:

  1. function (int $n): int { … } is a function without a name. It has a parameter, a return type and a body, like an ordinary function.
  2. $double = …; puts this function into the variable $double. The semicolon after } ends the assignment.
  3. $double(4) calls the function stored in the variable: the parentheses with the argument come right after the variable's name. The call returns 8.
  4. echo gettype($double) prints object: a function in a variable is a special kind of value, an object of the built-in class Closure. Classes and objects come in theme 11; for now it is enough that such a value can be called.

A function without a name

An anonymous function is a function without a name, written where a value is needed. You can assign it to a variable, pass it as an argument or return it from another function with return.

It is written differently from a named function:

  • right after the word function come the parentheses with the parameters, and there is no name;
  • the whole thing is an expression, so an assignment needs ; after }.

There is also a difference in timing. PHP learns a named function before the run, so a call may come above the declaration. An anonymous function appears only when the line with the assignment runs, so calling $double above that line ends in an error.

This is where the card picture is off. To give a real card to two people, you would have to copy it. But $g = $double makes no copy: both variables hold the same Closure object.

A callable parameter

Now let's pass a function to another function. The function apply takes a function $f and a number $x and returns the result of calling $f($x):

PHP
function apply(callable $f, int $x): int
{
    return $f($x);
}

echo apply($double, 7), "\n"; // 14
echo apply(function (int $n): int {
    return $n + 1;
}, 7), "\n"; // 8

Let's go step by step:

  1. callable $f is the parameter's type: only something that can be called fits here.
  2. Inside apply, the call $f($x) runs the function it received with the argument $x.
  3. apply($double, 7) passes the function from the variable without parentheses. It is not called right away but goes into apply, which returns 14.
  4. In the second call, the anonymous function is written right inside the call's parentheses. apply calls it with 7 and returns 8.

The function apply decides on its own when to call $f, like the pastry chef cooking from your card. A value that can be called with parentheses is a callable.

The callable type lets only callables into the function. If you pass a number to apply, PHP stops the program with a TypeError before the first line of the body.

A function's name in a string

A string holding a function's name is a callable too.

Take the built-in function abs: it returns the absolute value of a number, its distance from zero. abs(-5) is 5, and abs(5) is 5 as well. Let's pass it to apply by name:

PHP
echo apply('abs', -5), "\n"; // 5
$name = 'strtoupper';
echo $name('tea'), "\n"; // TEA
var_dump(is_callable('abs')); // bool(true)
var_dump(is_callable('shout')); // bool(false)

Here is what happens:

  1. apply('abs', -5) passes the string 'abs'. The callable type lets it in because it names an existing function, and the call $f($x) inside apply becomes abs(-5).
  2. $name('tea') calls the function whose name is in the variable, that is strtoupper('tea').
  3. is_callable checks whether a value can be called and returns true or false. The program has no function shout, so the second check prints bool(false).

A string with a name is handy when the function you need already exists: you do not have to write an anonymous one that only calls it.

Common mistake

The semicolon after the } of an anonymous function is missing:

PHP
<?php

$double = function (int $n): int {
    return $n * 2;
} // ✗
echo $double(4), "\n";
TEXT
Parse error: syntax error, unexpected token "echo"

PHP keeps reading the assignment and meets echo instead of ;. A parse error keeps the whole file from starting: not a single line runs.

A named function takes no semicolon after }, so people often forget it here. The fix is };, as in the first example.

Key points

  • An anonymous function is a function without a name; you put it in a variable and call it with parentheses: $double(4).
  • An assignment needs ; after the } of an anonymous function.
  • A callable parameter takes a callable, and the function runs it as $f($x).
  • A string with a function's name, such as 'abs', is a callable too; is_callable checks a value.