Функциональное программирование в PHP: от А до Я — полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в функциональное программирование на PHP

Функциональное программирование (ФП) — это парадигма, в которой вычисления рассматриваются как вычисление математических функций, избегая изменения состояния и изменяемых данных. Хотя PHP изначально создавался как императивный язык, начиная с версии 5.3 (2009 год) в него были добавлены мощные инструменты для функционального стиля: анонимные функции, замыкания, поддержка функций высшего порядка и многое другое.

В этой статье мы разберем все ключевые концепции функционального программирования в PHP — от базовых анонимных функций до продвинутых техник вроде каррирования и композиции функций. Вы узнаете, как писать более чистый, предсказуемый и тестируемый код.

1. Анонимные функции и замыкания (Closures)

Анонимные функции

Анонимная функция (лямбда) — это функция без имени. Она может быть присвоена переменной, передана как аргумент или возвращена из другой функции.

<?php
// Обычная анонимная функция
$square = function($n) {
    return $n * $n;
};

echo $square(5); // 25

// Анонимная функция как callback для array_map
$numbers = [1, 2, 3, 4];
$squared = array_map(function($n) {
    return $n * $n;
}, $numbers);

print_r($squared); // [1, 4, 9, 16]
?>

Замыкания (Closures)

Замыкание — это анонимная функция, которая может захватывать переменные из внешней области видимости с помощью ключевого слова use. Это одна из самых мощных возможностей ФП в PHP.

<?php
$multiplier = 3;

$multiply = function($n) use ($multiplier) {
    return $n * $multiplier;
};

echo $multiply(10); // 30

// Изменяемая переменная (передаётся по ссылке)
$counter = 0;
$increment = function() use (&$counter) {
    $counter++;
};

$increment();
$increment();
echo $counter; // 2
?>

2. Чистые функции и неизменяемость данных

Чистые функции

Чистая функция — это функция, которая:

  • Всегда возвращает одинаковый результат для одних и тех же аргументов (детерминирована)
  • Не имеет побочных эффектов (не изменяет внешние переменные, не выводит данные, не работает с БД)
<?php
// НЕ чистая функция (зависит от глобальной переменной)
$taxRate = 0.2;
function calculatePriceDirty($price) {
    global $taxRate;
    return $price * (1 + $taxRate);
}

// Чистая функция
function calculatePricePure($price, $taxRate) {
    return $price * (1 + $taxRate);
}

echo calculatePricePure(100, 0.2); // 120 — всегда предсказуемо
?>

Неизменяемость (Immutability)

В ФП принято не изменять существующие данные, а создавать новые. В PHP для этого можно использовать неизменяемые объекты или просто возвращать новые массивы.

<?php
// Плохо: изменение исходного массива
$numbers = [1, 2, 3];
array_push($numbers, 4); // мутация

// Хорошо: создание нового массива
$numbers = [1, 2, 3];
$newNumbers = array_merge($numbers, [4]);

// Функция, возвращающая новый массив
function addItem(array $arr, $item): array {
    $result = $arr;
    $result[] = $item;
    return $result;
}

$original = [1, 2];
$updated = addItem($original, 3);
print_r($original); // [1, 2] — исходный не изменился
print_r($updated);  // [1, 2, 3]
?>

3. Функции высшего порядка: array_map, array_filter, array_reduce

Функции высшего порядка — это функции, которые принимают другие функции как аргументы или возвращают их. В PHP встроены три ключевые функции для работы с массивами в функциональном стиле.

array_map — преобразование элементов

<?php
$users = [
    ['name' => 'Alice', 'age' => 25],
    ['name' => 'Bob', 'age' => 30],
];

// Извлекаем только имена
$names = array_map(function($user) {
    return $user['name'];
}, $users);

print_r($names); // ['Alice', 'Bob']

// Сокращённая запись со стрелочной функцией (PHP 7.4+)
$names = array_map(fn($user) => $user['name'], $users);
?>

array_filter — фильтрация элементов

<?php
$numbers = [1, 2, 3, 4, 5, 6];

// Оставляем только чётные числа
$even = array_filter($numbers, function($n) {
    return $n % 2 === 0;
});

print_r($even); // [1 => 2, 3 => 4, 5 => 6] — ключи сохраняются

// Сброс ключей
$even = array_values($even);
print_r($even); // [2, 4, 6]
?>

array_reduce — свертка массива в одно значение

<?php
$numbers = [1, 2, 3, 4, 5];

// Сумма всех чисел
$sum = array_reduce($numbers, function($carry, $item) {
    return $carry + $item;
}, 0);

echo $sum; // 15

// Произведение всех чисел
$product = array_reduce($numbers, function($carry, $item) {
    return $carry * $item;
}, 1);

echo $product; // 120
?>

4. Рекурсия и каррирование

Рекурсия

Рекурсия — когда функция вызывает саму себя. В ФП рекурсия часто заменяет итеративные циклы. Важно помнить о глубине рекурсии (в PHP по умолчанию ~100-256 вызовов).

<?php
// Факториал через рекурсию
function factorial($n) {
    if ($n <= 1) {
        return 1;
    }
    return $n * factorial($n - 1);
}

echo factorial(5); // 120

// Сумма элементов массива через рекурсию
function arraySumRecursive(array $arr) {
    if (empty($arr)) {
        return 0;
    }                

Блоги

Рекомендаций по книгам