array_push()实际需要多少个参数?

时间:2018-07-09 17:23:14

标签: php language-lawyer variadic-functions array-push

http://php.net/manual/en/function.array-push.php清楚地显示了函数的签名,可变参数是完全可选的:

int array_push ( array &$array [, mixed $... ] )

我认为,将array_push与splat运算符一起使用时,非常希望它接受空可变参数,例如允许这样的代码:

<?php

function add( array $arr1, array $arr2 ) {
    return \array_push($arr1, ...$arr2);
}

echo add(['foo'], ['bar']); // OK, returns 2
echo add(['foo'], []); // should be OK, but ain't currently - raises an E_WARNING
?>

出于这种确切原因,许多语言(例如Java)都允许函数中的空variadics(通常会导致无操作)。 PHP没有,至少在PHP 7.1和7.2中没有。

OTOH,尽管共享相似的语法定义,但array_merge和许多其他工具接受空的可变参数并使用上述splat语法正确工作:

var_dump( array_merge(['foo'], ...[]) ); // works for me.

我的问题是:

  1. 这实际上是预期的行为,文档错误,实现中的错误还是其他原因?
  2. (a)如果这是预期的行为,那么根据以上所述,其背后的原理是什么?
  3. (b)如果这是一个错误,为什么会发生?

注意:我已经在文档中检查了其他数组函数,例如http://php.net/manual/en/function.compact.phphttp://php.net/manual/en/function.array-merge.php等完全按照预期显示参数列表。

1 个答案:

答案 0 :(得分:3)

好吧,这个巨大的谜团似乎已经解决了:在浏览https://github.com/php/php-src/blob/master/ext/standard/array.c中的提交时,我发现了array_push的问题:

ZEND_PARSE_PARAMETERS_START(1, -1)
    Z_PARAM_ARRAY_EX(stack, 0, 1)
    Z_PARAM_VARIADIC('+', args, argc)
ZEND_PARSE_PARAMETERS_END();

第一行最近更改为ZEND_PARSE_PARAMETERS_START(2, -1),从而使该问题不存在。

https://github.com/php/php-src/commit/f7f48643e779111b23b546689b9fbb4e3affe1e7

引用:

  

php-7.3.0alpha1

     现在也可以使用单个参数来调用

array_push()和array_unshift(),这特别方便。点差运算符。

似乎既是文档错误,也是缺少的功能。 Yay for PHP 7.3开发人员可以实现此目的!