一文详解 PHP 的箭头函数和在 WordPrss 中的应用

PHP 的箭头函数(Arrow functions)也叫做“短闭包”(short closures),它是作为定义匿名函数的一种更简洁的方式,在 PHP 7.4 版本中被引入的。

箭头函数彻底改进了代码的简洁性,与传统的匿名函数不同,箭头函数无需显式定义参数即可无缝地访问相同作用域内的变量,此外也无需通过引用传递变量,或者使用 global 关键字。

箭头函数的语法

箭头函数使用 fn 关键字定义,后面紧跟着函数参数、箭头符号(=>)和函数体:

$func = fn() => VALUES TO RETUEN HERE

箭头函数在语法层面是更加简洁性的,可以显著减少闭包中常见的样板代码。

  1. 无需 function 关键字:箭头函数使用 fn 关键字来声明,而不是传统的 function 关键字。
  2. 隐式返回值:箭头函数的主体是一个表达式而不是一个语句块,该表达式的结果会被自动返回,所以不需要显式写 return 语句。
  3. 省略花括号:当箭头函数只包含一个表达式时,可以省略花括号 {}
  4. 捕获语法作用域变量:箭头函数会自动捕获定义时的语法作用域中的变量,而无需使用 use 关键字,这减少了闭包中常见的样板代码。

比如下面我们使用 array_map 求一组数字的平方的例子,可以明细看出箭头函数的简洁性:

$numbers	= [1, 2, 3, 4, 5];

// 使用传统的闭包函数:
$square		= array_map(function ($n) {
	return $n * $n;
}, $numbers);

// 使用箭头函数:
$square		= array_map(fn($n) => $n * $n, $numbers);

箭头函数变量作用域

箭头函数的一个显著优势是它还可以捕获周围作用域中的变量,与传统匿名函数不同,箭头函数继承了它们被定义时的作用域,这种语法作用域行为可以导致更可预测且错误更少的代码。

$multiplier	= 10;

// 使用传统的闭包函数:
$calculate	= function ($value) use ($multiplier){
	return $value * $multiplier;
};

// 使用箭头函数:
$calculate	= fn($value) => $value * $multiplier;

如上例子所示,传统的匿名函数使用 use 关键字从外部作用域导入 $multiplier 变量,相比之下,箭头函数自动继承变量,不需要使用 use 关键字了。

箭头函数的限制和约束

箭头函数虽然带来了简洁性,但是它同样也有是限制的,它的一个主要的约束就是箭头函数仅限于单个表达式。这种限制确保了简单性,但需要更复杂的逻辑时,使用传统的匿名函数可能会更合适。

// 使用传统的闭包函数:
$traditionalFunction	= function ($value) {
	if ($value > 0) {
		return true;
	} else {
		return false;
	}
};

// 使用箭头函数:
$arrowFunction	= fn($value) => $value > 0 ? true : false;

如上所示,如果需要在函数内使用多个语句,特别是涉及到控制流结构(如 if-else 代码块)时,传统的匿名函数(使用 function 关键字定义的函数)就显得更为适合,这是因为传统匿名函数可以包含任意数量的语句,并允许更复杂的逻辑,而箭头函数支持单个表达式。

箭头函数的具体例子

最简单的箭头函数

下面代码我们定义了一个名为 $add 简单箭头函数,它有两个参数 $a 和 $b,结果是返回它们的和。

$add = fn($a, $b) => $a + $b;

嵌套箭头函数

嵌套箭头函数涉及在一个箭头函数中使用另一个箭头函数,当需要动态定义函数或想要封装功能时,这尤其有用,下面是一个嵌套箭头函数的具体示例:

$outerFunction = fn($x) => fn($y) => $x * $y;

$result1 = $outerFunction(5)(3); // 输出:15
$result2 = $outerFunction(2)(4); // 输出:8

在 array_map 中使用

下面的例子我们在 array_map 中使用箭头函数求一组数字的平方:

$numbers = [1, 2, 3, 4, 5];

// 使用传统的闭包函数:
$squared = array_map(function($n) {
    return $n * $n;
}, $numbers);

// 使用箭头函数:
$squaredArrow = array_map(fn($n) => $n * $n, $numbers);

在 array_filter 中使用

下面的例子我们在 array_filter 中使用箭头函数过滤出一组数字的偶数:

$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// 使用传统的闭包函数:
$evenNumbers = array_filter($numbers, function($n) {
    return $n % 2 === 0;
});

// 使用箭头函数:
$evenNumbersArrow = array_filter($numbers, fn($n) => $n % 2 === 0);

在 array_reduce 中使用

下面的例子我们在 array_reduce 中使用箭头函数计算一组数字的和:

$numbers = [1, 2, 3, 4, 5];

// 使用传统的闭包函数:
$sumNumbers = array_reduce($numbers, function($carry, $number) {
    return $carry + $number;
}, 0);

// 使用箭头函数:
$sumNumbersArrow = array_reduce($numbers, fn($carry, $number) => $carry + $number, 0);

在 usort 中使用

下面的例子我们在 usort 中使用箭头函数对数组进行自定义排序:

$people = [
    ['name' => 'Alice', 'age' => 28],
    ['name' => 'Bob', 'age' => 22],
    ['name' => 'Charlie', 'age' => 25],
];

// 使用传统的闭包函数:
usort($people, function($a, $b) {
    return $a['age'] <=> $b['age'];
});

// 使用箭头函数:
usort($people, fn($a, $b) => $a['age'] <=> $b['age']);

在 WordPress 中使用

在 WordPress 中可以向上面的例子一样使用箭头函数,WordPress 中唯一需要知道的是,我们还可以在 WordPress 的 Hook 中使用箭头函数:

add_action('wp_loaded',	fn() => ob_start(fn($html) => apply_filters('wpjam_html', $html)));

比如上面代码,我们使用嵌套的方式,首先定一个箭头函数作为 wp_loaded 这个 action 的回调函数,这个函数在定义一个箭头函数作为 ob_start 的回调函数,这里只需要一行就搞定了,如果使用传统的闭包函数,则需要这样编码:

add_action('wp_loaded',	function(){
	return ob_start(function($html){
		return apply_filters('wpjam_html', $html);
	});
});

再举个使用 filter 的例子,比如 WPJAM Basic 中彻底关闭 WordPress 的 pingback 功能,他是这样处理的,就是把 XMLRPC 中 pingback 相关的方法简单返回 false

add_filter('xmlrpc_methods', fn($methods) => array_merge($methods, [
	'pingback.ping'						=> '__return_false',
	'pingback.extensions.getPingbacks'	=> '__return_false'
]));

如果使用传统的闭包函数,则需要这样编码:

add_filter('xmlrpc_methods', function($methods){
	return array_merge($methods, [
		'pingback.ping'						=> '__return_false',
		'pingback.extensions.getPingbacks'	=> '__return_false'
	]);
});

简单总结

1. 箭头函数是在 PHP 7.4 版本中引入,它提供一种更简洁的方式来写单行的闭包表达式,使代码更加清晰和简洁。

2. 箭头函数具有隐式返回特性,这意味着无需 return 语句即可自动返回表达式的结果。

3. 箭头函数会自动捕获上层作用域中的变量,所以在写类似数组操作的回调时,开发者不需要显式地使用 use 语句,这减少了闭包使用时的样板代码,并使得代码更易于理解。

4. 从上面例子可以看出,箭头函数对于高阶函数中使用的回调函数特别方便和适用,并且在 WordPress 的 Hook 中使用也非常方便。

5. 但是也要注意考虑到它只能包含单个表达式,当需要更复杂的逻辑时,使用传统的匿名函数可能会更合适。


©我爱水煮鱼,本站推荐使用的主机:阿里云,国外主机建议使用BlueHost

本站长期承接 WordPress 优化建站业务,请联系微信:「chenduopapa」。