Home Quizzes Leaderboard Competitions Learn Hire Us
About Contact
Log In Sign Up
Learn PHP Closures, Generators & Functional PHP

Closures, Generators & Functional PHP

⏱ 18 min read read
Closures in PHP:

Closures are anonymous functions stored in variables. Unlike Python, PHP
closures must explicitly import outer variables using use.

// Python captures outer variables automatically

// PHP requires 'use' keyword:

$multiplier = 3;

// WRONG --- $multiplier not available inside

$triple = function($x) { return $x * $multiplier; };

// CORRECT --- import with use

$triple = function($x) use ($multiplier) { return $x *
$multiplier; };

echo $triple(5); // 15

// Arrow functions (PHP 7.4+) capture automatically:

$triple = fn($x) => $x * $multiplier; // no 'use' needed!

echo $triple(5); // 15

Functional Array Functions:

// array_map --- transform every element

$doubled = array_map(fn($x) => $x * 2, [1, 2, 3, 4, 5]);

// [2, 4, 6, 8, 10]

// array_filter --- keep matching elements (preserves keys!)

$evens = array_filter([1,2,3,4,5,6], fn($x) => $x % 2 === 0);

// [1=>2, 3=>4, 5=>6] --- use array_values() to re-index

// array_reduce --- fold into single value

$sum = array_reduce([1,2,3,4,5], fn($carry, $item) => $carry +
$item, 0);

// 15

Generators --- Lazy Sequences:

function squares(int $n): Generator {

for ($i = 1; $i <= $n; $i++) {

yield $i => $i ** 2; // key => value

}

}

foreach (squares(5) as $n => $sq) {

echo "$n^2 = $sq\n";

}

// Memory-efficient --- values computed on demand, not all at once

PHP's array_filter preserves original keys --- always use
array_values() after to re-index.

Generators are perfect for large datasets, CSV rows, infinite
sequences.

Use fn() arrow functions (PHP 7.4+) --- cleaner than function() use()
for simple callbacks.
Code Example
<?php

// Closures --- must use 'use' for outer variables

$multiplier = 3;

$triple = fn($x) => $x * $multiplier; // arrow fn auto-captures

echo $triple(5) . "\n"; // 15

// Closure that returns a closure (factory pattern)

function makeMultiplier(int $factor): Closure {

return fn($x) => $x * $factor;

}

$double = makeMultiplier(2);

$triple = makeMultiplier(3);

echo $double(10) . "\n"; // 20

echo $triple(10) . "\n"; // 30

// array_map, array_filter, array_reduce

$nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

$doubled = array_map(fn($x) => $x * 2, $nums);

echo implode(', ', $doubled) . "\n"; // 2, 4, 6, ..., 20

$evens = array_values(array_filter($nums, fn($x) => $x % 2 ===
0));

echo implode(', ', $evens) . "\n"; // 2, 4, 6, 8, 10

$sum = array_reduce($nums, fn($carry, $item) => $carry +
$item, 0);

echo "Sum: $sum\n"; // 55

// Pipeline-style processing

$students = [

['name' => 'Alice', 'grade' => 92],

['name' => 'Bob', 'grade' => 58],

['name' => 'Carol', 'grade' => 85],

['name' => 'Dave', 'grade' => 45],

];

$passing = array_values(

array_filter($students, fn($s) => $s['grade'] >= 70)

);

usort($passing, fn($a, $b) => $b['grade'] <=>
$a['grade']);

$names = array_map(fn($s) => $s['name'], $passing);

echo implode(', ', $names) . "\n"; // Alice, Carol

// Generator --- lazy, memory-efficient

function fibonacci(): Generator {

[$a, $b] = [0, 1];

while (true) {

yield $a;

[$a, $b] = [$b, $a + $b];

}

}

$gen = fibonacci();

$first10 = [];

for ($i = 0; $i < 10; $i++) {

$first10[] = $gen->current();

$gen->next();

}

echo implode(', ', $first10) . "\n"; // 0, 1, 1, 2, 3, 5, 8,
13, 21, 34

?>
← Namespaces & Autoloading Working with Dates & Time →

Log in to track your progress and earn badges as you complete lessons.

Log In to Track Progress