Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

PHP Dictionary

  1. Home
  2. PHP Dictionary
  3. Arrow Functions (fn)

Arrow Functions (fn)

Since: PHP 7.0(2015)

Arrow functions (the『fn』keyword), added in『PHP』7.4, provide a concise syntax for short anonymous functions. Unlike closures written with the『function』keyword, they automatically capture variables from the outer scope without requiring『use』, making callback code cleaner and more compact.

Syntax

// Basic arrow function syntax
$functionName = fn(arg) => expression;

// No arguments
$functionName = fn() => expression;

// With type hints and return type
$functionName = fn(type $arg): returnType => expression;

// Traditional closure (for comparison)
$closure = function(arg) use ($outerVar) {
	return expression;
};

Differences Between Arrow Functions and Closures

ItemClosure (function)Arrow Function (fn)
Capturing outer variablesMust be explicitly declared with『use ($var)』.Automatically captures variables from the outer scope. No『use』required.
Capture typeBy value (default) or by reference (&) can be chosen.By value only. Capture by reference is not possible.
Body syntaxMultiple statements can be written inside『{ }』.A single expression only.『return』is not written (returned automatically).
Multi-line processingSupported. Complex logic can be written.Not supported. Not suitable when processing cannot fit in a single expression.
Use casesSuited for complex processing or side-effect-producing operations.Suited for simple value-returning operations such as transformations and filters.

Sample Code

Arrow Function Basics and Automatic Outer Variable Capture
arrow_basic.php
<?php
// Basic arrow function example using Steins;Gate character names

// ---- Closure (use required) ----
$labName = "Future Gadget Laboratory";

// In a closure, the outer variable $labName must be explicitly captured with use
$greetClosure = function(string $name) use ($labName): string {
	return $name . " is a member of " . $labName . ".";
};

echo $greetClosure("岡部倫太郎") . "\n";
echo $greetClosure("椎名まゆり") . "\n";

// ---- Arrow function (no use required) ----
// Arrow functions automatically capture outer variables
// $labName can be referenced directly without use
$greetArrow = fn(string $name): string => $name . " is a member of " . $labName . ".";

echo $greetArrow("阿万音鈴羽") . "\n";
echo $greetArrow("桐生萌郁") . "\n";

Running the code produces the following output:

php arrow_basic.php
岡部倫太郎 is a member of Future Gadget Laboratory.
椎名まゆり is a member of Future Gadget Laboratory.
阿万音鈴羽 is a member of Future Gadget Laboratory.
桐生萌郁 is a member of Future Gadget Laboratory.
Combining with array_map / array_filter
arrow_array_map_filter.php
<?php
// Example combining array_map / array_filter with arrow functions
// using Steins;Gate character data

$characters = [
	["name" => "岡部倫太郎", "divergence" => 1.048596, "isMember" => true],
	["name" => "牧瀬紅莉栖", "divergence" => 1.130205, "isMember" => true],
	["name" => "椎名まゆり", "divergence" => 1.048596, "isMember" => true],
	["name" => "阿万音鈴羽", "divergence" => 1.048596, "isMember" => true],
	["name" => "ビルゲイツ10世", "divergence" => 0.337187, "isMember" => false],
];

// array_map: build an array of labeled strings for each character
// Each element is transformed using an arrow function
$labels = array_map(
	fn($c) => $c["name"] . " (divergence: " . $c["divergence"] . ")",
	$characters
);
echo "--- All Characters ---\n";
foreach ($labels as $label) {
	echo $label . "\n";
}

// array_filter: extract only lab members
// The filter condition is specified with an arrow function
$members = array_filter(
	$characters,
	fn($c) => $c["isMember"] === true
);
echo "\n--- Lab Members Only ---\n";
foreach ($members as $member) {
	echo $member["name"] . "\n";
}

// Example of automatic outer variable capture
// Extract only characters on a specific world line
$targetDivergence = 1.048596;
$filtered = array_filter(
	$characters,
	// The arrow function can reference $targetDivergence without use
	fn($c) => $c["divergence"] === $targetDivergence
);
echo "\n--- Characters on world line " . $targetDivergence . " ---\n";
foreach ($filtered as $c) {
	echo $c["name"] . "\n";
}

Running the code produces the following output:

php arrow_array_map_filter.php
--- All Characters ---
岡部倫太郎 (divergence: 1.048596)
牧瀬紅莉栖 (divergence: 1.130205)
椎名まゆり (divergence: 1.048596)
阿万音鈴羽 (divergence: 1.048596)
ビルゲイツ10世 (divergence: 0.337187)

--- Lab Members Only ---
岡部倫太郎
牧瀬紅莉栖
椎名まゆり
阿万音鈴羽

--- Characters on world line 1.048596 ---
岡部倫太郎
椎名まゆり
阿万音鈴羽
Nested Arrow Functions and Multi-level Outer Variable Capture
arrow_nested.php
<?php
// Nested arrow functions also automatically capture variables from outer scopes
// With closures, each level of nesting requires its own use declaration

$worldLine = "Beta world line";
$organization = "SERN";

// The outer arrow function captures $worldLine,
// and the inner arrow function captures both $worldLine and $organization
$getInfo = fn(string $name) =>
	fn(int $labMemNo): string =>
		"Lab Member No." . $labMemNo . " " . $name
		. " (" . $worldLine . " / " . $organization . ")";

// Call the outer function first, then the inner function
$okabeInfo = $getInfo("岡部倫太郎");
echo $okabeInfo(1) . "\n";

$kurisu = $getInfo("牧瀬紅莉栖");
echo $kurisu(4) . "\n";

// Comparison: the same logic written with closures requires double use declarations
$getInfoClosure = function(string $name) use ($worldLine, $organization) {
	return function(int $labMemNo) use ($name, $worldLine, $organization): string {
		return "Lab Member No." . $labMemNo . " " . $name
			. " (" . $worldLine . " / " . $organization . ")";
	};
};

$mayuri = $getInfoClosure("椎名まゆり");
echo $mayuri(2) . "\n";

Running the code produces the following output:

php arrow_nested.php
Lab Member No.1 岡部倫太郎 (Beta world line / SERN)
Lab Member No.4 牧瀬紅莉栖 (Beta world line / SERN)
Lab Member No.2 椎名まゆり (Beta world line / SERN)

Applicable Situations and Limitations

ItemDetails
Suitable use casesSuited as callback arguments for functions like『array_map』,『array_filter』,『array_reduce』, and『usort』, where values are transformed, extracted, or compared simply.
Single-expression restrictionThe body can only contain a single expression. Use a closure when multiple statements or conditional branching is required.
No reference captureOuter variables are captured by value only. Modifying an outer variable from inside the arrow function is not possible. Use a closure with『use (&$var)』when modification is needed.
Not suited for recursionRecursive calls via a named variable are technically possible but reduce readability. Use a regular named function for recursive logic.
Return valueThe result of the expression is returned automatically. An explicit『return』is not written (writing one causes a syntax error).
PHP versionAvailable in PHP 7.4 and later. Not supported in PHP 7.3 or earlier.

Common Mistakes

Writing multiple statements in the arrow function body

The body of an arrow function can only contain a single expression. Trying to write multiple statements causes a syntax error.

ng_arrow_multi.php
<?php
$labName = "Future Gadget Laboratory";

// Trying to write multiple statements in the arrow function body (syntax error)
$greet = fn(string $name) => {
	$label = $name . " is a member of " . $labName . ".";
	return $label;
};

Running the code produces the following output:

php ng_arrow_multi.php
Parse error: syntax error, unexpected token "{" in ng_arrow_multi.php on line 5

When multiple statements are needed, use a closure with the function keyword.

ok_arrow_multi.php
<?php
$labName = "Future Gadget Laboratory";

// Use a closure when multiple statements are needed
$greet = function(string $name) use ($labName): string {
	$label = $name . " is a member of " . $labName . ".";
	return $label;
};

echo $greet("岡部倫太郎") . "\n";
echo $greet("椎名まゆり") . "\n";

Running the code produces the following output:

php ok_arrow_multi.php
岡部倫太郎 is a member of Future Gadget Laboratory.
椎名まゆり is a member of Future Gadget Laboratory.

Writing return in the arrow function body

In arrow functions, the result of the expression is returned automatically. Writing an explicit return causes a syntax error.

ng_arrow_return.php
<?php
$members = ["岡部倫太郎", "牧瀬紅莉栖", "阿万音鈴羽"];

// Writing return causes a syntax error
$upper = array_map(fn($name) => return strtoupper($name), $members);

Running the code produces the following output:

php ng_arrow_return.php
Parse error: syntax error, unexpected token "return" in ng_arrow_return.php on line 5

Write only an expression in the arrow function body. return is not needed.

ok_arrow_return.php
<?php
$divergences = [1.048596, 1.130205, 0.337187];

// No return needed. Write the expression directly
$rounded = array_map(fn($d) => round($d, 2), $divergences);

foreach ($rounded as $v) {
	echo $v . "\n";
}

Running the code produces the following output:

php ok_arrow_return.php
1.05
1.13
0.34

Trying to modify an outer variable from inside an arrow function

Arrow functions capture outer variables by value. Attempting to increment a counter or otherwise modify an outer variable inside an arrow function has no effect on the original variable.

ng_arrow_modify.php
<?php
$count = 0;
$members = ["岡部倫太郎", "牧瀬紅莉栖", "椎名まゆり"];

// Trying to modify $count inside the arrow function, but it is not reflected
array_walk($members, fn($name) => $count++);

echo $count . "\n"; // stays 0

Running the code produces the following output:

php ng_arrow_modify.php
0

To modify an outer variable, use a closure with use (&$var) for reference capture.

ok_arrow_modify.php
<?php
$count = 0;
$members = ["岡部倫太郎", "牧瀬紅莉栖", "椎名まゆり"];

// Use a closure with reference capture to modify the outer variable
array_walk($members, function($name) use (&$count) {
	$count++;
});

echo $count . "\n"; // 3

Running the code produces the following output:

php ok_arrow_modify.php
3

Summary

Arrow functions (the『fn』keyword) are a shorthand syntax added in PHP 7.4. Their defining feature is the ability to automatically capture variables from the outer scope without『use』.However, the body is limited to a single expression, and capture by reference is not possible.These restrictions mean that complex logic or operations with side effects still require traditional closures.

When using arrow functions as callbacks for『array_map』or『array_filter』, outer variables can be referenced naturally, keeping the code concise. Nested arrow functions also capture variables from each scope automatically, eliminating the need for multiple levels of『use』declarations as would be required with closures. For details on『array_map』and『array_filter』, see『array_map / array_filter』.

Both arrow functions and closures are function objects that can be assigned to variables or passed as arguments. Arrow functions are appropriate when the logic is short and simply returns a value; closures are appropriate when multiple statements are needed or when an outer variable must be modified. For details on closures, see『Anonymous Functions (Closures)』.

If you find any errors or copyright issues, please .