PHP 8: Modern PHP Development · Modern PHP Syntax & Types

Functions, Closures and First-Class Callables

Arrow functions, closures, first-class callable syntax and modern array helpers.

Arrow functions (fn($x) => $x * 2) capture outer variables by value automatically. Closures (function () use ($x) {}) capture explicitly. First-class callable syntax (8.1) creates a closure from any callable: strlen(...), $obj->method(...), Foo::bar(...). PHP 8 also added handy string functions (str_contains, str_starts_with, str_ends_with), 8.4 added array_find(), array_any() and array_all(), and 8.5 adds the pipe operator |> for chaining single-argument callables.

<?php
$prices = [12.5, 99.0, 45.0];
$withTax = array_map(fn(float $p) => round($p * 1.2, 2), $prices);

$upper = array_map(strtoupper(...), ['a', 'b']);        // first-class callable
$validator = $this->isValid(...);

if (str_contains($email, '@') && str_ends_with($email, '.com')) { /* ... */ }

$firstExpensive = array_find($prices, fn($p) => $p > 50);  // 99.0 (PHP 8.4)

// PHP 8.5 pipe operator
$slug = '  Hello World ' |> trim(...) |> strtolower(...) |> (fn($s) => str_replace(' ', '-', $s));

Common pitfalls

  • Arrow functions can only contain a single expression.
  • Arrow functions capture by value — modifying an outer variable inside has no effect outside.
  • Using string callables like 'strlen' loses static analysis; prefer strlen(...).

Key points

  • Arrow functions auto-capture by value
  • foo(...) creates closures from callables
  • Prefer built-in helpers like str_contains and array_find

Further reading: PHP manual: first-class callables

Practice questions

What's the difference between an arrow function and a regular closure regarding variable capture?

Answer

Arrow functions automatically capture any outer variables they use, by value. Regular closures capture nothing unless listed in use (...), and can capture by reference with use (&$x).

What does strlen(...) produce?

Answer

A Closure wrapping strlen (first-class callable syntax, PHP 8.1). It's type-safe and analyzable, unlike the string 'strlen'.

Open in the app to mark lessons complete, take notes and track your progress.