箭头函数

箭头函数是在 PHP 7.4 中引入的,作为 匿名函数 的更简洁语法。

匿名函数和箭头函数都使用 Closure 类实现。

箭头函数的基本形式为 fn (argument_list) => expr

箭头函数支持与 匿名函数 相同的功能,只是始终自动使用来自父作用域的变量。

当在表达式中使用的变量在父作用域中定义时,它将被隐式按值捕获。在以下示例中,函数 $fn1$fn2 的行为相同。

示例 #1 箭头函数自动按值捕获变量

<?php

$y
= 1;

$fn1 = fn($x) => $x + $y;
// 等同于按值使用 $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++; // 没有效果
$fn();
var_export($x); // 输出 1

?>

变更日志

版本 描述
7.4.0 箭头函数变得可用。

备注

注意: 可以在箭头函数内部使用 func_num_args()func_get_arg()func_get_args()

添加备注

用户贡献的备注 5 个备注

InvisibleSmiley
3 年前
与匿名函数不同,箭头函数不能有 void 返回类型声明。

可能看起来很明显,但如果您认为可以利用箭头函数的优势(使用来自父作用域的变量)来简化函数或方法调用,请记住,只有在您没有告诉 PHP 箭头函数确实返回 void 时才有可能。
itsunclexo at gmail dot com
3 年前
如您所知,变量绑定在箭头函数中是按“按值”进行的。这意味着,箭头函数返回在其中使用的变量的值的副本,而不是来自外部作用域的副本。

现在让我们看一个箭头函数返回引用而不是值副本的例子。

<?php

$x
= 0;

$fn = fn &(&$x) => $x; // 返回引用

$y = &$fn($x); // 现在 $y 代表引用

var_dump($y); // 输出:0

$y = 3; // 更改 $y 的值会影响 $x

var_dump($x); // 输出:3

?>
Koushil Mankali
4 年前
在示例 4(箭头函数无法修改来自外部作用域的值)中

<?php

$x
= 1;
$fn = fn() => $x++; // 没有效果
$fn();
var_export($x); // 输出 1

?>

在这里,我们可以在 fn(&$x) 中使用引用变量,并将值从函数调用 $fn($x) 传递过去,这样我们就可以通过不使用匿名函数来获得预期的输出。

示例

<?php

$x
= 1;
$fn = fn(&$x) => $x++;
$fn($x);
var_export($x);

?>

输出:2(如预期)

但是这里它不会自动从父作用域中获取值,我们必须显式地传递它们。
dexen dot devries at gmail dot com
4 年前
注意 compact() 无法访问(导入)外部作用域中的变量(在版本 7.4.0、7.4.8 中已知)(错误:https://bugs.php.net/bug.php?id=78970)。

有一个解决方法 - 直接使用变量;这将导致它被导入到箭头函数的命名空间中,并使其可供 compact() 使用。

<?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));
?>

结果
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
3 年前
<?php

$x
= 1;

(fn() => print(
$x))(); // 输出 1

(fn($x) => print($x))(2); // 输出 2
To Top