Navigation

Php

How to Use PHP's Arrow Functions (fn =>)

Use PHP 7.4+ arrow functions (fn =>) for concise, single-expression functions. Simplify callbacks and reduce code with automatic variable capture.

Table Of Contents

Problem

You need to write short, simple functions for callbacks and array operations, but regular anonymous functions require verbose syntax with use clauses.

Solution

// Traditional anonymous function
$numbers = [1, 2, 3, 4, 5];
$multiplier = 3;

$doubled = array_map(function($n) use ($multiplier) {
    return $n * $multiplier;
}, $numbers);

// Arrow function (much cleaner)
$doubled = array_map(fn($n) => $n * $multiplier, $numbers);

// Array filtering with arrow functions
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Filter even numbers
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
// Result: [2, 4, 6, 8, 10]

// Filter numbers greater than 5
$threshold = 5;
$greater = array_filter($numbers, fn($n) => $n > $threshold);
// Result: [6, 7, 8, 9, 10]

// Array transformation
$users = [
    ['name' => 'Alice', 'age' => 30],
    ['name' => 'Bob', 'age' => 25],
    ['name' => 'Charlie', 'age' => 35]
];

// Extract names
$names = array_map(fn($user) => $user['name'], $users);
// Result: ['Alice', 'Bob', 'Charlie']

// Create formatted strings
$formatted = array_map(
    fn($user) => "{$user['name']} ({$user['age']} years old)",
    $users
);

// Sorting with arrow functions
$products = [
    ['name' => 'Laptop', 'price' => 999],
    ['name' => 'Phone', 'price' => 599],
    ['name' => 'Tablet', 'price' => 299]
];

// Sort by price (ascending)
usort($products, fn($a, $b) => $a['price'] <=> $b['price']);

// Sort by name (alphabetical)
usort($products, fn($a, $b) => $a['name'] <=> $b['name']);

// Chaining operations
$numbers = range(1, 10);

$result = array_filter(
    array_map(fn($n) => $n * 2, $numbers),
    fn($n) => $n > 10
);
// Result: [12, 14, 16, 18, 20]

// Object method calls
class User {
    public string $name;
    public int $age;
    
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
    
    public function getInfo(): string {
        return "{$this->name} is {$this->age} years old";
    }
}

$users = [
    new User('Alice', 30),
    new User('Bob', 25),
    new User('Charlie', 35)
];

// Get user info
$info = array_map(fn($user) => $user->getInfo(), $users);

// Filter by age
$adults = array_filter($users, fn($user) => $user->age >= 18);

// Working with external variables
$config = [
    'tax_rate' => 0.08,
    'discount' => 0.1,
    'currency' => 'USD'
];

$prices = [100, 200, 300];

// Calculate total with tax
$withTax = array_map(
    fn($price) => $price * (1 + $config['tax_rate']),
    $prices
);

// Apply discount
$discounted = array_map(
    fn($price) => $price * (1 - $config['discount']),
    $prices
);

// Type hints with arrow functions
$strings = ['hello', 'world', 'php'];

$upperCase = array_map(fn(string $s): string => strtoupper($s), $strings);

// Multiple parameters
$coordinates = [
    [1, 2],
    [3, 4],
    [5, 6]
];

$distances = array_map(
    fn($point) => sqrt($point[0] ** 2 + $point[1] ** 2),
    $coordinates
);

// Nested arrow functions
$matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

$doubled = array_map(
    fn($row) => array_map(fn($cell) => $cell * 2, $row),
    $matrix
);

// Comparison with traditional functions
// Arrow function limitations:
// 1. Single expression only
// 2. Automatic return (no explicit return statement)
// 3. Cannot contain multiple statements

// Good for arrow functions
$squares = array_map(fn($n) => $n ** 2, [1, 2, 3, 4]);

// Bad for arrow functions - use traditional function
function complexOperation($data) {
    $processed = strtolower($data);
    $cleaned = trim($processed);
    
    if (strlen($cleaned) < 3) {
        throw new InvalidArgumentException('Too short');
    }
    
    return $cleaned;
}

// Practical examples
class DataProcessor {
    private array $filters = [];
    
    public function addFilter(callable $filter): self {
        $this->filters[] = $filter;
        return $this;
    }
    
    public function process(array $data): array {
        foreach ($this->filters as $filter) {
            $data = array_filter($data, $filter);
        }
        return $data;
    }
}

$processor = new DataProcessor();
$processor
    ->addFilter(fn($item) => $item > 0)
    ->addFilter(fn($item) => $item % 2 === 0)
    ->addFilter(fn($item) => $item < 100);

$result = $processor->process([1, 2, 3, 4, 50, 75, 100, 150]);
// Result: [2, 4, 50]

// API data transformation
$apiResponse = [
    ['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
    ['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com'],
    ['id' => 3, 'name' => 'Charlie', 'email' => 'charlie@example.com']
];

// Transform for frontend
$transformed = array_map(fn($user) => [
    'value' => $user['id'],
    'label' => $user['name'],
    'contact' => $user['email']
], $apiResponse);

Explanation

Arrow functions use fn($param) => expression syntax and automatically capture variables from parent scope. They're perfect for simple, single-expression callbacks.

Use arrow functions for array operations, sorting, and filtering. For complex logic with multiple statements, stick with traditional anonymous functions or named functions.

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Php