Closures & Arrow Functions

Functions in PHP are values — you can store them in variables, pass them as arguments, and return them from other functions. Master closures and the concise fn() => arrow syntax, and the whole world of array_map , array_filter and callbacks opens up.

Learn Closures & Arrow Functions in our free PHP course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.

Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

What You'll Learn in This Lesson

1️⃣ Anonymous Functions as Values

An anonymous function (also called a closure ) is a function with no name. You assign it to a variable and call it through that variable with () . Because it's just a value, you can also pass it into another function — any parameter typed callable will accept it.

2️⃣ Capturing Scope with use()

Here's the part that surprises newcomers: a PHP closure does not automatically see variables from the code around it. You import the ones you need with use(...) . By default use($x) captures a copy of the value at the moment the closure is defined. Add an ampersand — use(&$x) — to capture by reference so the closure and the outer code share one live variable.

3️⃣ Arrow Functions

Arrow functions (PHP 7.4+) are a compact closure for a single expression : fn($x) => $x * 2 . They have two superpowers over the long form: there's an implicit return , and they auto-capture outer variables by value — no use() needed. The trade-off is they're limited to one expression.

4️⃣ The Array-Function Trio

Closures really earn their keep with PHP's higher-order array functions. array_filter keeps items where your closure returns true , array_map transforms each item, and array_reduce folds a list down to a single value. Arrow functions make these read almost like English.

Now you try — fill in each ___ using the 👉 hint, then run it and check against the Output panel.

These lines build a by-reference counter closure — but they're scrambled. Put them in the order that prints 2 .

Initialise $n ( B ), define the closure that captures it by reference ( D ), call it twice ( A , E ) so $n becomes 2, then echo it ( C ). The closure must exist before you call it.

6 — the arrow function captured $x by value (5) when it was defined. Reassigning $x to 100 afterwards has no effect.

1,4,9 — each element is squared by the arrow function.

7 — capturing by reference ( &$total ) lets the closure mutate the outer variable across both calls.

📋 Quick Reference — Closures

No code is filled in this time — just a brief and an outline. Write it yourself, run it on onecompiler.com/php or your own machine, then check your result against the expected output in the comments.

Practice quiz

How does a classic closure (function (...) { ... }) access a variable from the surrounding scope?

  • Automatically, like JavaScript
  • Only with the global keyword
  • You must import it with use()
  • It cannot access outer variables

Answer: You must import it with use(). A PHP closure does not inherit outer scope automatically. You explicitly import variables with use($var).

What prints? $x = 5; $f = fn($n) => $n + $x; $x = 100; echo $f(1);

  • 6
  • 101
  • 1
  • 105

Answer: 6. The arrow function auto-captured $x by value (5) when defined. Reassigning $x to 100 afterwards has no effect, so 1 + 5 = 6.

What does use(&$x) with the ampersand do?

  • Captures a copy of $x
  • Makes $x read-only
  • Renames $x inside the closure
  • Captures $x by reference, sharing the live variable

Answer: Captures $x by reference, sharing the live variable. use(&$x) captures by reference: the closure shares the same variable as the outer scope and can read and modify the live value.

How do arrow functions (fn() =>) capture outer variables?

  • They require use()
  • They auto-capture by value any variable they reference
  • They auto-capture by reference
  • They cannot capture anything

Answer: They auto-capture by value any variable they reference. Arrow functions automatically capture by value any outer variable they mention — no use() needed.

What is the body limitation of an arrow function?

  • It is limited to a single expression
  • It can have at most 3 statements
  • It cannot take parameters
  • It cannot return a value

Answer: It is limited to a single expression. An arrow function (fn(...) => expression) is limited to one expression, with an implicit return. Use a full closure for multiple statements.

What does echo implode(',', array_map(fn($n) => $n * $n, [1, 2, 3])); print?

  • 1,2,3
  • 2,4,6
  • 1,4,9
  • 1,8,27

Answer: 1,4,9. array_map squares each element with the arrow function: 1, 4, 9.

With $tax = 0.2; $f = function ($p) use ($tax) { return $p + $p * $tax; }; then $tax = 0.5; what is $f(100)?

  • 150
  • 120
  • 100
  • 105

Answer: 120. use($tax) captured a copy of 0.2 at definition time. Changing $tax to 0.5 afterwards does not affect the closure, so 100 + 20 = 120.

Which array helper folds a list down to a single value?

  • array_map
  • array_filter
  • array_merge
  • array_reduce

Answer: array_reduce. array_reduce folds a list into one value (e.g. a running total); array_map transforms and array_filter keeps items.

What does the callable type hint mean?

  • Only a closure is accepted
  • method

Answer: method. callable means 'something you can call like a function' — a closure, a function name string, an [object, 'method'] array, or an invokable object.

After $total = 0; $add = function ($n) use (&$total) { $total += $n; }; $add(3); $add(4); what is $total?

  • 0
  • 3
  • 7
  • 4

Answer: 7. Capturing by reference (&$total) lets the closure mutate the outer variable across both calls: 3 + 4 = 7.