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

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

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

b是a的引用吗?


当前回答

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

试试下面的代码:

$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']对象,第二个输出日期保持不变。如果我只是将它设置为一个字符串,它也不会影响输出。

其他回答

默认情况下

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,这一次,数组是“通过引用”传递的。

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

当一个数组在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);

在PHP中,数组默认情况下是通过值传递给函数的,除非你显式地通过引用传递它们,如下面的代码片段所示:

$foo = array(11, 22, 33);

function hello($fooarg) {
  $fooarg[0] = 99;
}

function world(&$fooarg) {
  $fooarg[0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

输出如下:

array(3) {
  [0]=>
  int(11)
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  int(66)
  [1]=>
  int(22)
  [2]=>
  int(33)
}

为了扩展其中一个答案,多维数组的子数组也按值传递,除非显式地通过引用传递。

<?php
$foo = array( array(1,2,3), 22, 33);

function hello($fooarg) {
  $fooarg[0][0] = 99;
}

function world(&$fooarg) {
  $fooarg[0][0] = 66;
}

hello($foo);
var_dump($foo); // (original array not modified) array passed-by-value

world($foo);
var_dump($foo); // (original array modified) array passed-by-reference

结果是:

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}
array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(66)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  [1]=>
  int(22)
  [2]=>
  int(33)
}