php7处理特大数组,PHP 7新特性五 Spread operator(数组延展操作符)

PHP 7新特性五 Spread operator(数组延展操作符)

最后一次更新与:2020-08-21 18:43

发布与:2019-06-12 23:59

Look 4374访问

在数组表达式中对展开操作符(Spread Operator)支持的 RFC 投票是 绝大多数人赞同 将此功能添加到 PHP 7.4。

扩展运算符支持参数解包首先存在于 PHP 5.6 中,并且此 RFC 扩展了对数组的使用;扩展可以支持 Traversable 的数组和对象。这是 RFC 的一个基本示例:

$parts = ['apple', 'pear'];

$fruits = ['banana', 'orange', ...$parts, 'watermelon'];// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

/*以下是进一步的示例:*/

$arr1 = [1, 2, 3];

$arr2 = [...$arr1]; // [1, 2, 3]

$arr3 = [0, ...$arr1]; // [0, 1, 2, 3]

$arr4 = array(...$arr1, ...$arr2, 111); // [1, 2, 3, 1, 2, 3, 111]

$arr5 = [...$arr1, ...$arr1]; // [1, 2, 3, 1, 2, 3]

//定义函数

function getArr() {

return ['a', 'b'];

}

$arr6 = [...getArr(), 'c']; // ['a', 'b', 'c']

$arr7 = [...new ArrayIterator(['a', 'b', 'c'])]; // ['a', 'b', 'c']

function arrGen() {

for($i = 11; $i 

yield $i;

}

}

$arr8 = [...arrGen()]; // [11, 12, 13, 14]

函数调用中带有前缀的参数...将是“unpacked”:不是将参数本身传递给函数,而是传递它包含的元素(作为单独的参数)。这适用于数组和Traversables。

因此,以下所有函数调用都是等效的:

function test(...$args) { var_dump($args); }

test(1, 2, 3);                         // [1, 2, 3]

test(...[1, 2, 3]);                    // [1, 2, 3]

test(...new ArrayIterator([1, 2, 3])); // [1, 2, 3]

/*注意:解压缩像[1,2,3]这样的常量数组并没有多大意义。

通常这些会解压一些变量,比如... $ args*/

//可以...在调用中多次使用,并且可以在参数解包前使用普通参数:

$args1 = [1, 2, 3];

$args2 = [4, 5, 6];

test(...$args1, ...$args2); // [1, 2, 3, 4, 5, 6]

test(1, 2, 3, ...$args2);   // [1, 2, 3, 4, 5, 6]

//但是,在使用参数解包后,不可能使用普通参数。以下两个都是无效的:

//该...操作适用于所有的参数列表,包括new表达式:

fn(...$args);

$fn(...$args);

$obj->fn(...$args);

ClassName::fn(...$args);

new ClassName(...$args);

//参数解包不仅限于可变参数函数,它还可以用于“普通”函数:

function test($arg1, $arg2, $arg3 = null) {

var_dump($arg1, $arg2, $arg3);

}

test(...[1, 2]);       // 1, 2

test(...[1, 2, 3]);    // 1, 2, 3

test(...[1, 2, 3, 4]); // 1, 2, 3 (函数声明未捕获剩余的arg)

为了确保与命名参数的向前兼容性,解包操作符不支持字符串键。如果在解包期间遇到字符串键,则抛出可恢复的错误。如果使用自定义错误处理程序忽略错误,则不会解压缩其他参数,但仍会发生调用。

优于call_user_func_array的优点

call_user_func_array如果您还需要传递固定参数,则 使用会变得复杂。相比:

call_user_func_array([$db, 'query'], array_merge(array($query), $params));

// 对比

$db->query($query, ...$params);

call_user_func_array需要回调。因此,即使已知被调用的函数/方法,您仍然需要使用动态字符串/数组回调。这通常会排除任何IDE支持。

(new ReflectionClass('ClassName'))->newInstanceArgs($args);

// 对比

new ClassName(...$args);

call_user_func_array不适用于构造函数。而是ReflectionClass::newInstanceArgs()必须使用:

Futhermore call_user_func_array具有相当大的性能影响。如果大量的呼叫通过它,这可能会产生显着的差异。出于这个原因,项目1)经常用call_user_func_array以下形式的switch语句替换特别常见的调用:

switch (count($args)) {

case 0: $func(); break;

case 1: $func($args[0]); break;

case 2: $func($args[0], $args[1]); break;

case 3: $func($args[0], $args[1], $args[2]); break;

case 4: $func($args[0], $args[1], $args[2], $args[3]); break;

case 5: $func($args[0], $args[1], $args[2], $args[3], $args[4]); break;

default: call_user_func_array($func, $args); break;

}

该...参数拆包语法比快约3.5至4倍call_user_func_args。这解决了性能问题。基准代码和结果。

最后,如果存在可变参数语法,人们自然希望这种语法存在。因此,如果我们实现可变参数,那么最好也包括它。

PHP 7新特性五 Spread operator(数组延展操作符):https://www.yzdlm.com/php/29.html

上一篇:生气时还能保持冷静的人不会太差~~~

下一篇:【百度站长活动 6.4-6.14】答题送好礼,回帖就给发奖励【已结算】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值