5

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

这是来自 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

4 回答 4

4

这个调用php_array_merge_or_replace_wrapper的函数调用zend_hash_merge进而调用_zend_hash_merge等等等等,导致底层的memcmp()调用,这可能最终导致数组array_replace()通过引用传递到 PHP 中(因为memcmp()需要它们)。

数组是 PHP 的一个方面,它似乎只是工作并且很少受到质疑,经过一番挖掘,我可以明白为什么。

于 2012-06-22T14:22:34.273 回答
3

好吧,关键是_zend_hash_merge函数不仅由array_merge使用,而且还由+ 运算符使用(当它的两个操作数都是数组时)。

虽然在处理上存在一些差异,但实际上没有一个可以归因于需求的差异:据我所知,没有人写成+&$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 中有两种类型的引用?

于 2012-06-22T14:38:25.403 回答
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

结论:

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

于 2012-06-22T15:39:27.207 回答
1

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

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

于 2012-06-24T17:49:09.413 回答