PHP函数array_replace(),为什么参数传递的参数?

时间:2012-06-22 13:47:51

标签: php arrays php-5.3

PHP.net上用于array_replace()的函数签名表示数组将通过引用传入。以这种方式而不是按值进行的原因是什么(s)/好处,因为要获得预期的结果,必须将完成的数组返回给变量。为了清楚起见,我能够在手册中重现结果,因此这不是关于如何使用此功能的问题。

以下是来自php.net的函数签名和示例。

来源:http://ca3.php.net/manual/en/function.array-replace.php

功能签名:

array array_replace ( array &$array , array &$array1 [, array &$... ] )

示例代码:

$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");

$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);

以上示例将输出:

Array
(
    [0] => grape
    [1] => banana
    [2] => apple
    [3] => raspberry
    [4] => cherry
)

4 个答案:

答案 0 :(得分:4)

This function调用php_array_merge_or_replace_wrapper调用zend_hash_merge调用_zend_hash_merge等等等会导致潜在的memcmp()调用最终为什么数组通过引用传递到PHP的array_replace()(因为memcmp()要求它们)。

数组是PHP的一个方面,它似乎很有用,很少受到质疑,我可以在做一点挖掘之后看看为什么。

答案 1 :(得分:3)

嗯,关键是_zend_hash_merge函数不仅被array_merge使用 - 而且还被+ operator使用(当它的操作数都是数组时)。

虽然在处理方面存在一些差异,但实际上没有一个可以归因于需求的差异:据我所知,没有人将+写为&$arr + &$arr,它只是没有感。

所以我认为这只是文档中的一个错误。

但是,如果不分析PHP内部代码的深渊,就可以得出这个结论。 )记住,当我们传递一个可以(并且很可能会)被更改的数组时,我们使用&$array表示法 - 例如,参见array_splice()签名。并且(这可以很容易地检查)array_replace不会改变它的论点 - 至少目前是这样。 )

更新:好吧,现在我生气了。如果一些PHP开发者,上帝保佑他的灵魂,实际上认为这不是文档中的错误,让他/她解释为什么这样:

array_pop(array('a' => 1));

...触发了致命错误( Only variables can be passed by reference ),而这......

array_replace(array('a' => 1), array('b' => 2));

...只会工作,因为什么都没发生。

或者我们现在在PHP中有两种类型的引用?

答案 2 :(得分:1)

假设:

由于传递值涉及复制数组,我想通过引用传递它们会更快。

测试它:

<?php 

function ref(array &$array) {
    for($i = 0; $i < count($array); $i++) {
        $array[$i] == 'foo'; //just accessing
    }
}

function val(array $array) {
    for($i = 0; $i < count($array); $i++) {
        $array[$i] == 'foo'; //just accessing
    }
}


//create large array
$array = array();
for($i = 0; $i < 100; $i++) {
    $array[] = $i;
}


echo "Pass by reference\n";
$t1 = microtime(true);
for($i = 0; $i < 10000; $i++) {
    ref($array);
}
$t2 = microtime(true);
echo $t2 - $t1 . "s\n\n";

echo "Pass by value\n";
$t1 = microtime(true);
for($i = 0; $i < 10000; $i++) {
    val($array);
}
$t2 = microtime(true);
echo $t2 - $t1 . "s\n\n";

输出:

Pass by reference
8.3282010555267s

Pass by value
1.4845979213715s

结论:

显然,这不是出于性能原因。

答案 3 :(得分:1)

这是一个文档错误,现在已经修复。

https://bugs.php.net/bug.php?id=62383