PHP 中的箭头函数是在 PHP 7.4 中引入的。它们略有不同。
fn 关键字
新的fn 关键字是now a reserved keyword。
以前,我们继续使用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,那么你会得到一个错误
传递给 {closure}() 的参数必须是 int 或 null 类型,给定字符串,在第 y 行的 x 中调用
嵌套箭头函数
$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?
For quick online testing 只需将这些代码粘贴到那里
对于您的本机系统,我刚刚克隆了 this branch of php-src 并使用 GCC 和 make 编译它。我通过 test.php 文件和命令行进行了测试,以检查一切是否正常。
核心参考 - https://wiki.php.net/rfc/arrow_functions_v2