> В чем разница короткого синтаксиса функций fn и замыканий в PHP (PHP)

Уровень: senior · Роль: backend · Язык: PHP · Категория: Технические вопросы

Компании: vanta

Стек: PHP

> Пример ответа

Короткий ответ

Короткий синтаксис fn - это стрелочная функция, которая автоматически захватывает переменные из внешней области по значению и всегда возвращает выражение. Замыкание (Closure) - это анонимная функция, которая требует явного указания use для захвата переменных и может содержать несколько операторов. Основное различие - в синтаксисе, области видимости и ограничениях: fn компактнее, но менее гибкая.

Подробное объяснение

Стрелочные функции (fn) появились в PHP 7.4. Их ключевые особенности:

  • Автоматический захват переменных из родительской области по значению - не нужно писать use.
  • Всегда возвращают значение - тело состоит из одного выражения.
  • Не могут содержать несколько операторов или return с блоками.
  • Не могут изменять захваченные переменные (только по значению).

Замыкания (Closure) - это классические анонимные функции, доступные с PHP 5.3. Они:

  • Требуют явного указания use ($var) для захвата внешних переменных.
  • Могут содержать произвольное количество операторов.
  • Могут захватывать переменные по ссылке (use (&$var)).
  • Могут иметь return в любом месте тела.

Разница также проявляется в контексте использования:

  • fn удобна для коротких колбэков в array_map, array_filter, usort.
  • Closure нужна для более сложной логики, где требуется несколько шагов или изменение внешнего состояния.

Важный нюанс: fn всегда возвращает значение, даже если вы не пишете return явно - это неявный return выражения. У Closure возврат опционален.

На практике

При выборе между fn и Closure руководствуйтесь:

  • Если логика умещается в одно выражение - используйте fn.
  • Если нужно несколько операторов, циклы, условия - используйте Closure.
  • Если нужно изменить внешнюю переменную - только Closure с use (&$var).
  • Если нужно захватить много переменных - fn делает это автоматически, что сокращает код.

Пример из реального кода: сортировка массива объектов по полю:

PHP
// с fn
usort($users, fn($a, $b) => $a->age <=> $b->age);
// с Closure
usort($users, function($a, $b) use ($sortField) {
if ($a->$sortField == $b->$sortField) {
return 0;
}
return ($a->$sortField < $b->$sortField) ? -1 : 1;
});

Пример кода

PHP
$multiplier = 3;
// стрелочная функция - автоматический захват
$double = fn($x) => $x * 2;
$triple = fn($x) => $x * $multiplier;
// замыкание - явный захват
$quadruple = function($x) use ($multiplier) {
return $x * $multiplier * 2;
};
// замыкание с изменением внешней переменной
$counter = 0;
$increment = function() use (&$counter) {
$counter++;
};
// fn не может изменить внешнюю переменную
// $bad = fn() => $counter++; // ошибка: нельзя присвоить значение
echo $double(5); // 10
echo $triple(5); // 15
echo $quadruple(5); // 30
$increment();
echo $counter; // 1

Как отвечать на собеседовании

Начните с краткого определения обоих конструкций. Затем перечислите ключевые различия: автоматический захват переменных, ограничение на одно выражение, невозможность изменения внешних переменных. Приведите пример, где fn удобнее, и пример, где без Closure не обойтись. Упомяните версии PHP, где появились эти возможности. Если спросят про производительность - отметьте, что разница минимальна, но fn может быть чуть быстрее из-за меньшего количества операций.

Что проверяет интервьюер

Интервьюер проверяет:

  • Понимание синтаксических различий и ограничений fn.
  • Знание механизма захвата переменных (по значению vs по ссылке).
  • Умение выбрать правильный инструмент под задачу.
  • Понимание области видимости в анонимных функциях.
  • Знание версий PHP и истории развития языка.

Типичные ошибки

  • Утверждение, что fn - это просто сокращение для function, без упоминания ограничений.
  • Забывают, что fn не может изменять внешние переменные.
  • Путают захват по значению и по ссылке.
  • Говорят, что fn появилась в PHP 7.0 или 7.3 (на самом деле 7.4).
  • Не упоминают, что fn всегда возвращает значение, даже без явного return.
  • Считают, что fn можно использовать для многострочной логики - это не так.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью