为什么函数签名在 array_map 和 array_filter/array_reduce 之间不同?

Why does the function signature differ between array_map and array_filter/array_reduce?

array_map 要求输入 $array 作为最后一个参数。 array_filterarray_reduce$array 输入作为第一个参数。作为对比示例,当您在 JavaScript 中的数组上调用 map、filter 或 reduce 时,回调函数签名看起来像

(current, index, array) => {…}

Array.prototype.reduce以结转值作为第一个参数,但JavaScript方法中仍然不能搞错参数的顺序。

我知道 PHP 不是面向功能的,但我想知道是什么设计决策导致了 array_map 等的签名。

array_map 将数组作为最后一个参数仅仅是因为您可以提供任意数量的数组(可变参数)吗?通过 array_map 的回调函数提供任意数量的数组的能力是否比拥有更统一的函数签名更重要?

编辑/评论:

来自维基百科,这表明 PHP 已经进化了多长时间:

'Early PHP was not intended to be a new programming language, and grew organically, with Lerdorf noting in retrospect: "I don’t know how to stop it, there was never any intent to write a programming language […] I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way." A development team began to form and, after months of work and beta testing, officially released PHP/FI 2 in November 1997. The fact that PHP was not originally designed but instead was developed organically has led to inconsistent naming of functions and inconsistent ordering of their parameters. In some cases, the function names were chosen to match the lower-level libraries which PHP was "wrapping", while in some very early versions of PHP the length of the function names was used internally as a hash function, so names were chosen to improve the distribution of hash values.'

Does array_map take an array as the last parameter simply because you can feed as many arrays as you want (variadic)?

是;只有方法签名中的最后一个参数可以是可变的。

Does the ability to feed an arbitrary number of arrays through the callback function of array_map outweigh having more uniform function signatures?

本质上,这是在询问 array_map 是否应该接受多个数组。允许使用多个数组调用 array_map 有很好的用例;下面是 PHP array_map 指南中的示例,我稍作修改:

<?php
function showLanguages($n, $s, $g)
{
    return("The number $n is called $s in Spanish and $g in German.");
}

$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");
$c = array("eins", "zwei", "drei", "vier", "funf");

$d = array_map("showLanguages", $a, $b, $c);
print_r($d);

如果将 array_map 更改为将多维数组作为第一个参数会怎样?虽然从技术上讲它会使函数签名更加统一,但实际上会增加一些额外的问题。

底层代码不仅必须验证第一个参数是一个数组,还必须验证它是一个 array 数组。这将使它本质上是一种不同于数组的参数,因此它 仍然 是与其他 array_* 方法不同的方法签名。

如果您真的想将回调作为最后一个参数,您可以使用修改后的函数来删除最后一个元素,将其移至第一个参数,然后对其调用 array_map。但是,您会失去所有类型提示,因此会更难使用。

/*
 * Accepts a variable number of arrays as the first N arguments, takes a callback as the last argument
 */
function map()
{
    $args = func_get_args();

    $callback = array_pop($args);

    array_unshift($args, $callback);

    return call_user_func_array("array_map", $args);
}