Мне стало известно о стрелочные функции в PHP 7.4. Я пытался использовать их как
<?php
$num = 1;
$arrowfunction = () => {
return $num + 1;
}
echo $arrowfunction();
Потому что я увидел оператор => в пулреквесте. Так же, как javascript.
Я ожидал, что на выходе будет «2», но это не сработало! я получил
Parse error: syntax error, unexpected ')' in /test.php on line 3
Этот вопрос (и ответ на него) был очень полезен для меня. Я не знал, что в 7.4 есть функции стрелок.
@SeanBright большое спасибо, и да, я думаю, это поощряется stackoverflow.blog/2011/07/01/…
конечно, это должен быть вопрос по теме в первую очередь? и это путь к широкому.
Да, я только что протестировал их все и упомянул об этом здесь, поэтому, если люди хотят спросить об областях, ключевых словах или чем-то еще в этом отношении, они могут обратиться сюда @SeanBright.
Я думаю, что это нужно было добавить в Справочник — что означает этот символ в PHP? вместо нового вопроса и ответа.
@JohnConde Это была первая мысль, которая пришла мне в голову, но она создаст некоторую путаницу, поскольку у нас есть много ответов, касающихся символа стрелки stackoverflow.com/questions/1241819stackoverflow.com/questions/1655336stackoverflow.com/questions/4758791 Итак, я подумал, что для этого нужны новые вопросы и ответы.






Стрелочные функции в PHP представлены в PHP 7.4. Это немного отличается.
Новое ключевое слово fn — теперь зарезервированное ключевое слово.
Раньше мы продолжали использовать ключевое слово function.
$add = function ($valone,$valtwo) {
return $valone + $valtwo;
};
$add(1,2) // 3
С появлением новых стрелочных функций:
$add = fn($valone,$valtwo) => $valone + $valtwo;
$add(1,2) // 3
Ранее мы должны были использовать ключевое слово use для участие переменной из родительской области.
$y = 1;
$fn = function ($x) use ($y) {
return $x + $y;
};
echo $fn(2); // 3
Выражение, определенное в родительской области, будет неявно, захваченным по значению.
$y = 1;
$fn = fn($x) => $x + $y;
echo $fn(2); // 3
Вышеприведенное следует для переменной $this внутри методов класса.
class foo {
public function test() {
$context = fn() => var_dump($this);
$context();
}
}
$test = new foo();
$test->test(); // object(foo)#1 (0) { }
Как и раньше, мы использовали для выполнения наших операций использование ключевого слова use для получения переменной из родительской области, поэтому это означает, что мы не можем записать значение переменной из функции в верхнюю область.
$y = 1;
$fn = fn() => $y++;
$fn(); // Has no effect
echo $y // 1
Если мы думаем присвоить значение другой переменной из замыкания, то это тоже не сработает
$y = 1;
$f = 0;
$fn = fn() => $f = $y + 1;
$fn();
echo $f; // 0
Это совершенно новое в PHP, это позволяет нам определить тип функции, переменную и значение, которое возвращает функция.
fn(int $x) => $x; // the argument type must be (int)
fn(): int => $x; // type of return value (int)
Ошибки возникают, когда определенный тип аргумента не помещается в аргумент при вызове функции. Ошибку можно поймать, используя тип TypeError
$var = 10;
$int_fn = fn(int $x): int => $x;
var_dump($int_fn($var)); // int(10)
try {
$int_fn("foo");
} catch (TypeError $e) {
echo $e->getMessage(), "\n"; // Argument 1 passed to {closure}() must be of the type int, string given, called in x on line y
}
В PHP 7.1 они поддерживают ?type в аргументах, что также позволяет аргументу быть нулевым.
$funn = fn(?int... $args): array => $args;
var_dump($funn(20, null, 30)); // Array(3) { [0]=> int(20) [1]=> NULL [2]=> int(30) }
Если вы укажете строку или что-то еще, а не int для вышеуказанной функции, вы получите сообщение об ошибке
Argument passed to {closure}() must be of the type int or null, string given, called in x on line y
$var = 6;
var_dump((fn() => fn() => $var)()()); // int(6)
var_dump((fn() => function() use($var) { return $var; })()()); // int(6)
Любые возможные ошибки внутри замыкания не брошены, если не вызвано
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$b = 1;
fn() => $b + $c; // no error, nothing
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$b = 1;
(fn() => $b + $c)(); // Notice: Undefined variable: c in the location on line x
Если отчеты об ошибках отключены, вы просто получите int(1)
Как использовать PHP. 7.4 сейчас?
Для быстрого онлайн-тестирования просто вставьте туда этот код
Для вашей родной системы я просто клонировал эта ветка php-src и скомпилировал его с помощью GCC и make. Я провел тестирование с помощью файла test.php и командной строки, чтобы проверить, все ли работает.
Основная ссылка — https://wiki.php.net/rfc/arrow_functions_v2
Я добавил еще один ответ о IIFE Ссылка. Что означает эта ошибка в PHP?. Вы можете улучшить его, если хотите.
Также стоило бы упомянуть Как использовать $this внутри закрытия php?
В некоторых ситуациях стрелочные функции могут сделать ваш код короче и читабельнее. В первую очередь они были разработаны с мыслью об использовании их для простых обратных вызовов. В качестве примера рассмотрим usort(), который принимает функцию обратного вызова в качестве пользовательского параметра.
До PHP 7 вам приходилось делать что-то подобное, чтобы определить собственный обратный вызов для usort():
// old syntax prior to PHP 7
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = [3, 2, 5, 6, 1];
usort($a, "cmp");
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
В PHP 7 добавлен оператор космического корабля, и теперь благодаря стрелочным функциям вы можете сделать свой код намного чище.
// New syntax since PHP 7.4
$a = [3, 2, 5, 6, 1];
usort($a, fn($a, $b) => $a<=>$b);
foreach ($a as $key => $value) {
echo "$key: $value\n";
}
Попробуйте онлайн на 3v4l.org
Анонимные функции в PHP могут быть довольно многословными, даже если они выполняют только простую операцию, отсюда и причина более короткого синтаксиса. В качестве другого примера рассмотрим следующую функцию:
// Returns an array with each element squared - old syntax
function array_square($arr) {
return array_map(function($x) { return $x*$x; }, $arr);
}
// Returns an array with each element squared - new syntax
function array_square($arr) {
return array_map(fn($x) => $x**2, $arr);
}
print_r(array_square([1,2,3,4,5]));
Сокращение ненужного синтаксиса помогает понять реальную цель кода, но имейте в виду, что короче не всегда значит чище! Я бы рекомендовал относиться к стрелочным функциям с той же осторожностью, что и к тернарным операторам. Используйте их только тогда, когда вы знаете, что это улучшает читабельность, а не только для того, чтобы сделать ваш код короче.
Поэтому я изначально проголосовал за это, потому что это, очевидно, вопрос, который был задан исключительно для того, чтобы вы могли на него ответить. По-видимому, это поощряется (вики-сообщество все еще существует?), поэтому я отозвал отрицательный голос ... неохотно.