Arrow Functions

JA JASWANT Updated 30 Oct 2026
7 min read ·Lesson 194 of 209

What Is an Arrow Function?

In simple terms: An arrow function is a short way to write a small anonymous function whose whole job is to calculate and return one expression. Technically: Arrow functions (PHP 7.4+) use the syntax fn(parameters) => expression. The expression's value is returned automatically. Arrow functions are Closure objects, like anonymous functions, but they automatically capture any variable from the surrounding scope that they use — by value — so no use clause is needed.

// Anonymous function
$withTax = function (float $amount) use ($rate): float {
    return $amount * (1 + $rate / 100);
};
// Arrow function — same behavior
$withTax = fn(float $amount): float => $amount * (1 + $rate / 100);

Why Arrow Functions Were Added

Most callbacks passed to array_map(), array_filter(), and usort() are one-liners. With anonymous functions, they need function, use, return, braces, and a semicolon. Arrow functions remove that noise, making short callbacks easier to read.


Syntax

fn(parameters): ReturnType => expression
PartMeaning
fnKeyword that starts an arrow function
(parameters)Parameters, with optional types and defaults
: ReturnTypeOptional return type
=>Separates parameters from the expression
expressionA single expression; its value is returned

Example

<?php
$double = fn(int $n): int => $n * 2;
$fullName = fn(string $first, string $last): string => "$first $last";
$isAdult = fn(int $age): bool => $age >= 18;
echo $double(21) . "\n";
echo $fullName('Priya', 'Sharma') . "\n";
var_dump($isAdult(16));

Output

42
Priya Sharma
bool(false)

There is no return keyword: the value of the expression after => is the return value.


Automatic Capture of Outer Variables

Arrow functions can use variables from the surrounding scope directly:

<?php
$gstPercent = 18;
$withGst = fn(float $amount): float => round($amount * (1 + $gstPercent / 100), 2);
echo $withGst(100) . "\n";
echo $withGst(250) . "\n";

Output

118
295

$gstPercent is captured automatically. Only variables that are actually used in the expression are captured.

Captured by Value, at Creation Time

<?php
$gstPercent = 18;
$withGst = fn(float $amount): float => $amount * (1 + $gstPercent / 100);
$gstPercent = 28;   // changed after the arrow function was created
echo $withGst(100) . "\n";

Output

118

The arrow function captured 18 when it was created. Later changes to $gstPercent do not affect it.

Arrow Functions Cannot Modify Outer Variables

Because variables are captured by value, changes inside the arrow function affect only its copy:

<?php
$count = 0;
$increment = fn() => $count++;
$increment();
$increment();
echo "Count: $count\n";

Output

Count: 0

The outer $count is unchanged. There is no way to capture by reference in an arrow function — use an anonymous function with use (&$count) when shared state is needed.


Arrow Functions With Array Functions

This is where arrow functions shine:

<?php
$prices = [499, 1299, 89, 2499];
$names = ['Karthikeyan', 'Anu', 'Meena', 'Bala'];
$stock = ['Keyboard' => 12, 'Mouse' => 0, 'Monitor' => 4];
$doubled = array_map(fn(int $p): int => $p * 2, $prices);
$affordable = array_filter($prices, fn(int $p): bool => $p < 1000);
$available = array_filter($stock, fn(int $qty): bool => $qty > 0);
usort($names, fn(string $a, string $b): int => strlen($a) <=> strlen($b));
echo implode(', ', $doubled) . "\n";
echo implode(', ', $affordable) . "\n";
echo implode(', ', array_keys($available)) . "\n";
echo implode(', ', $names) . "\n";

Output

998, 2598, 178, 4998
499, 89
Keyboard, Monitor
Anu, Bala, Meena, Karthikeyan

Each callback fits on one line and reads almost like a description: "map each price to price × 2", "keep prices under 1000", "sort names by length".


Nested Arrow Functions

An arrow function can return another arrow function. Inner functions also capture variables automatically, including parameters of the outer function:

<?php
$multiplier = fn(int $x): Closure => fn(int $y): int => $x * $y;
$triple = $multiplier(3);
echo $triple(4) . "\n";
echo $multiplier(5)(6) . "\n";

Output

12
30

$multiplier(3) returns a new arrow function that remembers $x = 3. $multiplier(5)(6) creates and immediately calls such a function.


Limitations of Arrow Functions

LimitationConsequenceAlternative
Only one expressionNo multiple statements, loops, or if blocksAnonymous function with a body
Captures by value onlyCannot change outer variablesfunction () use (&$x) { ... }
Always returns the expression's valueCannot be a "statement-only" function in the usual senseAnonymous function

Expressions can still be fairly rich — ternaries, match, function calls, and the null coalescing operator are all expressions:

<?php
$label = fn(int $stock): string => match (true) {
    $stock === 0 => 'Out of stock',
    $stock < 5 => "Only $stock left",
    default => 'In stock',
};
foreach ([0, 3, 20] as $qty) {
    echo $label($qty) . "\n";
}

Output

Out of stock
Only 3 left
In stock

If an arrow function becomes hard to read on one or two lines, switch to an anonymous or named function.


Arrow Functions vs Anonymous Functions

FeatureArrow FunctionAnonymous Function
IntroducedPHP 7.4PHP 5.3
Syntaxfn($x) => $x * 2function ($x) { return $x * 2; }
BodySingle expressionAny statements
returnImplicitExplicit
Outer variablesCaptured automatically, by valueCaptured explicitly with use (by value or reference)
$this in classesBound automaticallyBound automatically
static formstatic fn(...) => ...static function (...) { ... }
Best forShort callbacks and small transformationsMulti-step logic, shared state

Practical Example: Order Report

<?php
$orders = [
    ['id' => 1, 'customer' => 'Asha', 'total' => 1250, 'status' => 'paid'],
    ['id' => 2, 'customer' => 'Bala', 'total' => 640, 'status' => 'pending'],
    ['id' => 3, 'customer' => 'Charu', 'total' => 3200, 'status' => 'paid'],
    ['id' => 4, 'customer' => 'Dev', 'total' => 980, 'status' => 'paid'],
];
$minimumTotal = 1000;
$largePaidOrders = array_filter(
    $orders,
    fn(array $order): bool => $order['status'] === 'paid' && $order['total'] >= $minimumTotal
);
$lines = array_map(
    fn(array $order): string => "#{$order['id']} {$order['customer']}: ₹" . number_format($order['total']),
    $largePaidOrders
);
$sum = array_sum(array_column($largePaidOrders, 'total'));
echo implode("\n", $lines) . "\n";
echo "Total: ₹" . number_format($sum) . "\n";

Output

#1 Asha: ₹1,250
#3 Charu: ₹3,200
Total: ₹4,450

Step-by-Step Explanation

  1. The filter arrow function captures $minimumTotal automatically and keeps paid orders of at least ₹1,000. Dev's order (₹980) is excluded by the minimum, and Bala's by its status.
  2. The map arrow function converts each remaining order into a formatted line.
  3. array_column() extracts the totals, and array_sum() adds them.
  4. Each step is a small, readable expression; no temporary loops or counters are needed.

Arrow Functions and the Pipe Operator (PHP 8.5+)

The pipe operator |> passes a value through a sequence of single-argument callables. Arrow functions used in a pipe must be wrapped in parentheses:

<?php
$slug = '  PHP Arrow Functions  '
    |> trim(...)
    |> strtolower(...)
    |> (fn(string $s): string => str_replace(' ', '-', $s));
echo $slug;

Output

php-arrow-functions

This requires PHP 8.5. On earlier versions, use nested calls or intermediate variables.


Common Mistakes

Trying to Use Multiple Statements

$fn = fn($x) => { $y = $x * 2; return $y; };   // parse error

Fix: Use an anonymous function for multi-statement logic.

Expecting Changes to Outer Variables

Effect: Outer variables stay unchanged because they were captured by value. Fix: Return the new value, or use an anonymous function with use (&$var).

Writing return in the Expression

$fn = fn($x) => return $x * 2;   // parse error

Fix: The expression itself is returned: fn($x) => $x * 2.

Overly Long Arrow Functions

Effect: Dense one-liners that are hard to read and debug. Fix: Extract the logic into a named function and pass it with first-class callable syntax.


Best Practices

  • Use arrow functions for short, single-expression callbacks.
  • Add parameter and return types even in short callbacks.
  • Rely on automatic capture for read-only values; use anonymous functions for shared state.
  • Prefer static fn inside classes when $this is not needed.
  • Switch to a named function when the expression stops being obvious at a glance. Official reference: https://www.php.net/manual/en/functions.arrow.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings Function Arguments PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer PHP Form Handling PHP XML Parsers PDO Transactions PDO Error Handling PHP XML Parsers PHP SimpleXML Parser PHP SimpleXML - Get PHP XML Expat Parser PHP DOM Parser PHP XMLReader PHP XMLWriter AJAX Intro PHP Class Constants Encryption with Sodium Recursive Functions Variable Functions Anonymous Functions Closures Arrow Functions First-class Callable Syntax PHP Arrays Indexed Arrays Associative Arrays Create Arrays Variables Scope Static Variables Variable Variables PHP Echo / Print PHP printf / sprintf PHP Data Types PHP Booleans PHP NULL PHP Strings String Functions
Ask about this post
AI Ask about this post

Ask questions about Arrow Functions and get answers drawn from it.

Signed-in readers only.