箭头函数
箭头函数是 PHP 7.4 的新语法,是一种更简洁的 匿名函数 写法。
箭头函数的基本语法为
fn (argument_list) => expr
。
箭头函数支持与 匿名函数 相同的功能,只是其父作用域的变量总是自动的。
当表达式中使用的变量是在父作用域中定义的,它将被隐式地按值捕获。在下面的例子中,函数 $fn1 和 $fn2 的行为是一样的。
示例 #1 箭头函数自动捕捉变量的值
<?php
$y = 1;
$fn1 = fn($x) => $x + $y;
// 相当于通过 value 使用 $y:
$fn2 = function ($x) use ($y) {
return $x + $y;
};
var_export($fn1(3));
?>
以上例程会输出:
4
在箭头函数嵌套的情况下同样有效。
示例 #2 箭头函数自动捕捉变量的值,即使在嵌套的情况下
<?php
$z = 1;
$fn = fn($x) => fn($y) => $x * $y + $z;
// 输出 51
var_export($fn(5)(10));
?>
和匿名函数一样,箭头函数语法同样允许标准的函数声明,包括参数和返回类型、缺省值、变量,以及通过引用传递和返回。以下都是箭头函数的有效例子。
示例 #3 合法的箭头函数例子
<?php
fn(array $x) => $x;
static fn(): int => $x;
fn($x = 42) => $x;
fn(&$x) => $x;
fn&($x) => $x;
fn($x, ...$rest) => $rest;
?>
箭头函数会自动绑定上下文变量,这相当于对箭头函数内部使用的每一个变量 $x 执行了一个
use($x)
。这意味着不可能修改外部作用域的任何值,若要实现对值的修改,可以使用
匿名函数 来替代。
示例 #4 来自外部范围的值不能在箭头函数内修改
<?php
$x = 1;
$fn = fn() => $x++; // 不会影响 x 的值
$fn();
var_export($x); // 输出 1
?>
更新日志
版本 | 说明 |
---|---|
7.4.0 | 新增箭头函数语法。 |
注释
注意: 可以对箭头函数使用 func_num_args(), func_get_arg(), 和 func_get_args() 函数。

User Contributed Notes 5 notes
InvisibleSmiley ¶
1 year ago
Unlike anonymous functions, arrow functions cannot have a void return type declaration.
May seem obvious, but if you thought you could make use of the benefits of arrow functions (using variables from the parent scope) to simplify a function or method call, keep in mind that this is only possible if you do NOT tell PHP that the arrow function does indeed return void.
Koushil Mankali ¶
1 year ago
In example 4 (Values from the outer scope cannot be modified by arrow functions)
<?php
$x = 1;
$fn = fn() => $x++; // Has no effect
$fn();
var_export($x); // Outputs 1
?>
Here we can use reference variable in fn(&$x) and pass the value from function call $fn($x) so that we will get the output as expected with out using Anonymous functions.
Example:
<?php
$x = 1;
$fn = fn(&$x) => $x++;
$fn($x);
var_export($x);
?>
Output : 2 (as expected)
But here it will not take values from parent scope automatically but we have to pass them explicitly.
itsunclexo at gmail dot com ¶
1 year ago
As you already know, variable bindings occur in arrow functions by "by-value". That means, an arrow function returns a copy of the value of the variable used in it from the outer scope.
Now let us see an example of how a arrow function returns a reference instead of a copy of a value.
<?php
$x = 0;
$fn = fn &(&$x) => $x; // Returns a reference
$y = &$fn($x); // Now $y represents the reference
var_dump($y); // Outputs: 0
$y = 3; // Changing value of $y affects $x
var_dump($x); // Ouputs: 3
?>
dexen dot devries at gmail dot com ¶
1 year ago
Beware compact() not being able to access (import) variables from external scope (known in versions: 7.4.0, 7.4.8) (bug: https://bugs.php.net/bug.php?id=78970).
A workaround is available - use the variable directly; this will cause it to be imported into the arrow function's namespace and make it available to the compact() too.
<?php
$aa = 111;
$accessing_variable_works = fn($bb) => [ $aa, $bb ];
$compact_is_broken = fn($bb) => compact('aa', 'bb');
$compact_can_work_with_workaround = fn($bb) => compact('aa', 'bb') + ['workaround' => $aa];
var_dump($accessing_variable_works(333));
var_dump($compact_is_broken(555));
var_dump($compact_can_work_with_workaround(777));
?>
result:
array(2) {
[0]=>
int(111)
[1]=>
int(333)
}
PHP Notice: compact(): Undefined variable: aa in /home/m/vlt/guitar/tlb/s/public_html/index.php on line 9
array(1) {
["bb"]=>
int(555)
}
array(3) {
["aa"]=>
int(111)
["bb"]=>
int(777)
["workaround"]=>
int(111)
}
zhangchengming at kkguan dot com ¶
1 year ago
<?php
$x = 1;
(fn() => print($x))(); // Outputs 1
(fn($x) => print($x))(2); // Outputs 2