Стрелочные функции в PHP
Краткие анонимные функции, они же, стрелочные функции - один простой способ быстрого и простого синтаксиса описания функции в PHP. Запись в таком формате удобна и полезна, когда мы описываем функцию для функций array_map
, array_filter
, или им подобным.
Вот, как выглядит эта запись:
// массив пользователей
$users = [/*...*/];
$ids = array_map(fn($user) => $user->id, $users);
Вместо старого синтаксиса:
$users = [/*...*/];
$ids = array_map(function($user) {
return $user->id;
}, $users);
Итого, теперь давайте проясним особенности использования стрелочных функций в PHP:
- Они становятся доступными в PHP 7.4
- Функции начинаются с ключевого слова
fn
- Они могут иметь только одно выражение, которое являет собой
return
выражение - Не нужно указывать ключевое слово
return
- Функциям могут задаваться возвращаемые типы и типы аргументам
Например, рассмотрим пример описания стрелочной функции с указанием типов аргумента и возврата:
$users = [/*...*/];
$ids = array_map(fn(User $user): int => $user->id, $users);
Стоит так же отметить 2 ключевые особенности:
- В таких функциях доступен оператор распаковки аргументов (Spread)
- Ссылки разрешены как в качестве аргументов, так и в качестве возвращаемых значений
Если вы хотите вернуть значение по ссылке, вы должны использовать синтаксис, показанный ниже:
fn&($val) => $val
Если коротко описать их функциональность, то стрелочные функции в PHP имеют те же функциональные возможности, что и обычные анонимные функции, за исключением того, что они описываются только одним выражением.
Скажи нет многострочным функциям
Работая с JavaScript, в ваших глазах может проснуться надежда на то, что в PHP так же можно описать стрелочную функцию указывая несколько выражений. Однако, это не так, и на протяжении всей статья и повторяю одну и ту же идею: стрелочная функция описывается в одну строку, и вы не можете использовать несколько строк для её описания.
Причина кроется в том, что цель коротких замыканий - уменьшить длину синтаксиса их создания. Благодаря ключевому слову fn
, и пропуск return
, запись функций, однозначно, стала короче. А сам создатель RFC, Никита Попов, говорит, что если вы работаете с многострочными функциями, то с помощью стрелочных функций вы получите меньше выгоды от этого, потому, было принято решение отказаться от этой возможности.
В конце концов, многострочные стрелочные функции, по определению, являются длинными и многословными, что не совсем соответствует концепции короткой анонимной функции. И одно лишь упущение оператора return
и замена ключевого слова function
на fn
, не вносит существенной разницы и профита.
Соглашаться с этим мнение или нет - решать вам. Остаётся только терпеть, использоваться и довольствоваться тем, что имеем ^^. Хотя надежда есть: в будущем, возможно, будет предусмотрена возможность создания многострочных стрелочных функций.
Значения из внешней области
Ещё одно существенное различие между короткими и обычными анонимными функциями заключается в том, что для стрелочных функций не требуется ключевое слово use
для доступа к данным из внешней области видимости.
$modifier = 5;
array_map(fn($x) => $x * $modifier, $numbers);
Важно отметить, что вы не можете изменять переменные из внешней области видимости. Значения передаются значением, а не ссылкой. Это означает, что вы можете изменить переменную $modifier
в пределах заданной функции, однако это не повлияет изменение переменной $modifier
во внешней области видимости.
Исключением является ключевое слово $this
, которое действует точно так же, как и в обычных анонимных функциях:
array_map(fn($x) => $x * $this->modifier, $numbers);
Будущие возможности
Я уже упоминал о многострочных стрелочных функциях, которые по-прежнему возможны в будущих версиях PHP. Но ещё одна обсуждаемая идея - использование короткого синтаксиса функций в классах, например для методов геттеров и сеттеров:
class User {
private $name;
fn getName() => $this->name;
}
В общем, стрелочные функции в PHP - желанное и полезное обновление, хотя есть ещё пространство для их улучшения. Самым большим из них, вероятно, являются добавление многостраничных стрелочных функций.
Дополнительные примеры
Вот пример того, как мы делали раньше, и как это выглядит по новому синтаксису:
$extended = function ($c) use ($callable, $factory) {
return $callable($factory($c), $c);
};
//со стрелочной функцией:
$extended = fn($c) => $callable($factory($c), $c);
А в Laravel это выглядит так:
// Сейчас
$users->map(function($user) {
return $user->first_name.' '.$user->last_name;
});
// Со стрелочной функцией
$users->map(
fn($user) => $user->first_name.' '.$user->last_name
);
Резюме
В этой статье вы узнали, какие возможности определения функций были добавлены в PHP 7.4, как работать со стрелочными функциями в PHP, как создать многостраничную стрелочную функцию в PHP, с какой версии они появились, и что нового появится в ближайшем, вероятном будущем. Следите за обновлениями, обновляйте ПО, учите новое и внедряйте новинки.