Стрелочные функции в PHP

Стрелочные функции в 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, с какой версии они появились, и что нового появится в ближайшем, вероятном будущем. Следите за обновлениями, обновляйте ПО, учите новое и внедряйте новинки.