PHP 5.6 之前是使用函数 func_num_args()
,func_get_arg()
,和 func_get_args()
实现传递可变参数列表 。
PHP 可变参数(...)
PHP 5.6 引进了 ... 操作符,官方名称是 splat operator,或者 spread operator(数组延展操作符),也有人称为 Argument unpacking(参数解包)。
具体看 PHP 官方提供的例子就好了:
使用 ... 来访问变量参数
代码语言:javascript复制function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc = $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
输出:10
使用 ... 来传递参数
代码语言:javascript复制function add($a, $b) {
return $a $b;
}
echo add(...[1, 2])."n";
$a = [1, 2];
echo add(...$a);
上面都是输出:3
多个参数
可变参数之前,还可以有别的参数,但是后面就不能有别的参数了,比如下面的例子:
代码语言:javascript复制function display($name, ...$args){
echo '名称:'.$name;
echo '其他信息:';
print_r($args);
}
实际应用例子
我们拿 WordPress 中判断当前用户是否有权限的函数 current_user_can()
来举例,说明 ... 这个操作符如何改善的代码可读性的。
在 PHP 5.6 之前的代码:
代码语言:javascript复制function current_user_can( $capability ) {
$current_user = wp_get_current_user();
if ( empty( $current_user ) ) {
return false;
}
$args = array_slice( func_get_args(), 1 );
$args = array_merge( array( $capability ), $args );
return call_user_func_array( array( $current_user, 'has_cap' ), $args );
}
在没有看完所有函数代码情况下,大多数程序员都会假设这个函数只有 $capability
这一参数,但是该函数是接受可变数量参数的,WordPress 必须使用 func_get_args()
来获取所有参数,然后切开数组分片,然后再合并回去。
虽然功能实现了,但是这样编码非常不爽。现在看看使用了 ... 操作符之后的代码:
代码语言:javascript复制function current_user_can( $capability, ...$args ) {
$current_user = wp_get_current_user();
if ( empty( $current_user ) ) {
return false;
}
return $current_user->has_cap( $capability, ...$args );
}
首先在函数定义中就清楚地看到 ...$args
参数,然后传递数据也变得更加清晰,无需数组的切片和合并处理,也无需使用 call_user_func_array
回调方法,代码非常直观可读。