IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    Denis | 邓鸿华发表于 2024-01-08 06:45:24
    love 0

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

    © WordPress果酱 / RSS 订阅 / 长期承接 WordPress 项目



沪ICP备19023445号-2号
友情链接