1)当一个数组作为参数传递给一个方法或函数时,它是通过引用传递,还是通过值传递?

2)将数组赋值给变量时,新变量是对原始数组的引用,还是新复制? 这样做怎么样:

$a = array(1,2,3);
$b = $a;

b是a的引用吗?


当前回答

默认情况下

Primitives are passed by value. Unlikely to Java, string is primitive in PHP Arrays of primitives are passed by value Objects are passed by reference Arrays of objects are passed by value (the array) but each object is passed by reference. <?php $obj=new stdClass(); $obj->field='world'; $original=array($obj); function example($hello) { $hello[0]->field='mundo'; // change will be applied in $original $hello[1]=new stdClass(); // change will not be applied in $original $ } example($original); var_dump($original); // array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } }

注意:作为一种优化,每个单独的值都作为引用传递,直到它在函数内部被修改。如果它被修改,并且值是通过引用传递的,那么它会被复制,副本也会被修改。

其他回答

关于你的问题的第二部分,请参阅手册的数组页,其中声明(引用):

数组赋值总是涉及到值 复制。使用引用操作符to 通过引用复制数组。

下面举个例子:

<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 is changed,
             // $arr1 is still array(2, 3)

$arr3 = &$arr1;
$arr3[] = 4; // now $arr1 and $arr3 are the same
?>

对于第一部分,最好的方法是尝试;-)

考虑下面的代码示例:

function my_func($a) {
    $a[] = 30;
}

$arr = array(10, 20);
my_func($arr);
var_dump($arr);

它会给出这样的输出:

array
  0 => int 10
  1 => int 20

这表明函数没有修改作为参数传递的“外部”数组:它是作为副本传递的,而不是引用。

如果你想通过引用传递它,你必须修改函数,如下所示:

function my_func(& $a) {
    $a[] = 30;
}

输出将变成:

array
  0 => int 10
  1 => int 20
  2 => int 30

As,这一次,数组是“通过引用”传递的。

不要犹豫,阅读手册的参考资料解释部分:它应该可以回答你的一些问题;-)

默认情况下

Primitives are passed by value. Unlikely to Java, string is primitive in PHP Arrays of primitives are passed by value Objects are passed by reference Arrays of objects are passed by value (the array) but each object is passed by reference. <?php $obj=new stdClass(); $obj->field='world'; $original=array($obj); function example($hello) { $hello[0]->field='mundo'; // change will be applied in $original $hello[1]=new stdClass(); // change will not be applied in $original $ } example($original); var_dump($original); // array(1) { [0]=> object(stdClass)#1 (1) { ["field"]=> string(5) "mundo" } }

注意:作为一种优化,每个单独的值都作为引用传递,直到它在函数内部被修改。如果它被修改,并且值是通过引用传递的,那么它会被复制,副本也会被修改。

这个帖子有点老了,但这里有一些我刚刚发现的东西:

试试下面的代码:

$date = new DateTime();
$arr = ['date' => $date];

echo $date->format('Ymd') . '<br>';
mytest($arr);
echo $date->format('Ymd') . '<br>';

function mytest($params = []) {
    if (isset($params['date'])) {
        $params['date']->add(new DateInterval('P1D'));
    }
}

http://codepad.viper-7.com/gwPYMw

注意,$params参数没有amp,它仍然会改变$arr['date']的值。这与这里的其他解释以及我之前的想法并不相符。

如果我克隆$params['date']对象,第二个输出日期保持不变。如果我只是将它设置为一个字符串,它也不会影响输出。

当一个数组在PHP中传递给一个方法或函数时,它是按值传递的,除非你显式地通过引用传递它,就像这样:

function test(&$array) {
    $array['new'] = 'hey';
}

$a = $array(1,2,3);
// prints [0=>1,1=>2,2=>3]
var_dump($a);
test($a);
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

在第二个问题中,$b不是$a的引用,而是$a的副本。

就像第一个例子一样,你可以通过以下方式引用$a:

$a = array(1,2,3);
$b = &$a;
// prints [0=>1,1=>2,2=>3]
var_dump($b);
$b['new'] = 'hey';
// prints [0=>1,1=>2,2=>3,'new'=>'hey']
var_dump($a);

关于你的第一个问题,数组是通过引用传递的,除非它在你调用的方法/函数中被修改。如果您试图在方法/函数中修改数组,则首先创建它的副本,然后只修改副本。这使得数组看起来好像是按值传递的,而实际上不是。

例如,在第一种情况下,即使你没有通过引用定义你的函数来接受$my_array(通过在参数定义中使用&字符),它仍然通过引用传递(即:你不会用不必要的拷贝浪费内存)。

function handle_array($my_array) {  

    // ... read from but do not modify $my_array
    print_r($my_array);

    // ... $my_array effectively passed by reference since no copy is made
}

但是,如果您修改了数组,则首先生成它的副本(这会使用更多内存,但不影响原始数组)。

function handle_array($my_array) {

    // ... modify $my_array
    $my_array[] = "New value";

    // ... $my_array effectively passed by value since requires local copy
}

供你参考——这就是所谓的“惰性复制”或“写时复制”。