【问题标题】:Are objects in array passed by reference?数组中的对象是通过引用传递的吗?
【发布时间】:2011-09-30 07:38:54
【问题描述】:

在这种情况下,

class my_class {

    public __construct($params = array()){

        **** do something
    } 

 }

 $other_object = new some_class();

 $object = new my_class(array(
                         'var1' => 'test' 
                         'object' => $other_object));

$other_object 将通过引用还是按值传递?

【问题讨论】:

标签: php arrays object reference


【解决方案1】:

自 PHP 5 起 PHP 对象变量包含对实际变量的引用或标识符。这里有一个例子来证明这一点。

class test{
public $test = 1;
}

$obj1 = new test;
$orginal = [$obj1,array(2),3];
$copy = $orginal;
echo 'orginal array';
var_dump($orginal);
echo 'copy of orginal';
var_dump($copy);

//after changing
$copy[0]->test = 'changed';
$copy[1][0] = 'changed';
$copy[3] = 'changed';
echo 'orginal array after changing its copy';
var_dump($original);
echo 'copy of orginal after changing';
var_dump($copy);

输出是

original array
array (size=3)
  0 => 
    object(test)[38]
      public 'test' => int 1
  1 => 
    array (size=1)
      0 => int 2
  2 => int 3

copy of original
array (size=3)
  0 => 
    object(test)[38]
      public 'test' => int 1
  1 => 
    array (size=1)
      0 => int 2
  2 => int 3

original array after changing its copy
array (size=3)
  0 => 
    object(test)[38]
      public 'test' => string 'changed' (length=7)
  1 => 
    array (size=1)
      0 => int 2
  2 => int 3

copy of original after changing
array (size=3)
  0 => 
    object(test)[38]
      public 'test' => string 'changed' (length=7)
  1 => 
    array (size=1)
      0 => string 'changed' (length=7)
  2 => string 'changed' (length=7)

当副本中的对象发生变化时,原始对象也会发生变化,但数组和变量保持不变,因为它们是作为值传递的。

有关对象引用的更多信息请参阅:Objects and reference

【讨论】:

    【解决方案2】:

    PHP 5 中的对象总是通过引用传递。在debug_zval_dump() 的帮助下,您可以检查变量的 refcount 以计算对对象实例的引用数。注意文档中的注释,你会发现很多关于将变量传递给函数的有趣的事情。

    【讨论】:

      【解决方案3】:

      php 中的对象是按值传递的。详情请见this answer

      【讨论】:

      • php.net/language.references 链接背后的答案是关于“PHP 没有任何引用,因为在 C 中没有任何引用”。这一点都没有错,但是因为 PHP 本身在其手册中详细描述了它对引用的理解,所以当我们只停留在 PHP 上下文中时,它是错误的。可以说:网址是对网站的引用。没错,但从 C 的角度来看它是错误的。
      【解决方案4】:

      对象总是引用,除非你明确地clone 它。

      您可以使用spl_object_hash() 检索“对象ID”,然后将它们相互比较。请记住,一旦垃圾收集器从内存中删除了一个对象,该 ID 可能会被重用。

      【讨论】:

      • 奇怪,这不是我遇到的行为。 $tmp = $array[0]; $tmp['item'] = "something"; var_dump($array); \\ original values
      • @WORMSS 有什么意义?您修改$tmp 并期望$array 改变?这当然行不通。
      • 我希望它会改变,因为正如您刚才所说,对象是引用。 $array[0] 中有一个对象。你说“这当然行不通”,但我 5 年来第一次从主要做 javascript 回到 PHP。如果你这样做 var tmp = arr[0]; tmp['item'] = "something"; console.log(arr); Arr[0] 已经改变,因为它是通过引用传递的。如果你说对象作为引用传递,但数组中的这个对象表现得像一个值,我称之为奇怪的行为。
      • @WORMSS 不,它是原始类型。但实际的问题是:$array[0] 是什么?
      • 对不起,这是另一个关联数组。但是仅仅知道数组是所有这些问题的原始答案。就像我说的,我从长期使用 Javascript 回到 PHP,其中数组是对象。所以我不认为 PHP 中的数组是原始的。现在我知道了,这很有意义。
      【解决方案5】:

      这是一个示例,它显示了每个位置的引用对象...http://codepad.org/HK6Oo4xL

      【讨论】:

      • 这些东西都是你手写的吗?
      猜你喜欢
      • 2011-12-11
      • 2021-09-11
      • 2011-02-12
      • 1970-01-01
      • 2011-05-11
      • 2014-10-23
      • 1970-01-01
      • 2017-09-11
      相关资源
      最近更新 更多