【问题标题】:Any reason PHP don't iterate array by reference?PHP不通过引用迭代数组的任何原因?
【发布时间】:2011-01-24 18:11:59
【问题描述】:
$arr = array(array(array()));
foreach($arr as $subarr)
{
 $subarr[] = 1;
}
var_dump($arr);

输出:

array(1) {
  [0]=>
  array(1) {
    [0]=>
    array(0) {
    }
  }
}

但对于对象,它是参考:

class testclass {
}

$arr = array(new testclass());
foreach($arr as $subarr)
{
 $subarr->new = 1;
}
var_dump($arr);

输出:

array(1) {
  [0]=>
  object(testclass)#1 (1) {
    ["new"]=>
    int(1)
  }
}

为什么将arrayobject 区别对待?

【问题讨论】:

    标签: php arrays object loops


    【解决方案1】:

    PHP 通过引用传递所有对象。 (PHP5?)

    PHP 按值传递所有数组。

    最初 PHP 通过值传递对象和数组,但为了减少创建的对象数量,它们将对象切换为自动通过引用传递。

    PHP 不通过引用传递数组并没有真正合乎逻辑的原因,但这正是该语言的工作原理。如果需要,可以按值迭代数组,但必须通过引用显式声明值:

    foreach ( $myArray as &$val ){
        $val = 1; //updates the element in $myArray
    }
    

    感谢Yacoby 提供的示例。

    坦率地说,我更喜欢按值传递数组,因为数组是一种基本数据结构,而对象是更复杂的数据结构。目前的系统是有道理的,至少对我来说是这样。

    【讨论】:

    • 所以我们可以通过引用和值来迭代数组,但是如何通过值来迭代对象呢?
    • @user198729 除了 Chacha 的建议,您可以实现迭代器接口并确保 current 返回 byval 而不是 byref。见php.net/manual/en/language.oop5.iterations.php
    【解决方案2】:

    为什么数组和对象会被同等对待?

    PHP 只是通过引用 (->) 传递对象,并通过值传递所有数组。

    如果所有对象都按值传递,脚本会复制同一个类的多个副本,从而占用更多内存。

    【讨论】:

      【解决方案3】:

      Foreach 复制迭代数组,因为它允许您在foreach 内修改原始数组,并且使用这种方式更容易。不是这样吗,你的第一个例子会爆炸。没有办法阻止 PHP 复制 foreach 中的数组。即使使用按引用传递项语法foreach($foo as &$bar),您仍将处理数组的副本,其中包含引用而不是实际值。

      另一方面,大多数面向对象的开发人员都希望对象总是通过引用传递。在 PHP 5 中就是这种情况。当你复制一个包含对象的数组时,实际上是在复制对对象的引用。因此,即使您正在处理数组的副本,您也在处理相同的对象。

      如果要复制对象,请使用clone 运算符。据我所知,没有办法让某些对象总是按值传递。

      $foo = new Foo;
      $bar = clone $foo;
      

      【讨论】:

        猜你喜欢
        • 2015-12-08
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        • 2015-09-25
        • 2011-01-13
        • 1970-01-01
        • 2019-05-26
        • 2021-05-09
        相关资源
        最近更新 更多