通过引用传递;为啥原始对象没有改变?
Posted
技术标签:
【中文标题】通过引用传递;为啥原始对象没有改变?【英文标题】:Passing by reference; why is the original object not changed?通过引用传递;为什么原始对象没有改变? 【发布时间】:2011-09-04 02:59:54 【问题描述】:如果在 php5 中对象是通过引用传递的,那么为什么下面的 $foo
不会改变?
$foo = array(1, 2, 3);
$foo = (object)$foo;
$x = $foo; // $x = &$foo makes $foo (5)!
$x = (object)array(5);
print_r($foo); // still 1,2,3
所以:
引用传递不一样 分配。
那为什么下面的$foo
是(100, 2, 3)
?
$foo = array('xxx' => 1, 'yyy' => 2, 'zzz' => 3);
$foo = (object)$foo;
$x = $foo;
$x->xxx = 100;
print_r($foo);
【问题讨论】:
还有,这不是很混乱吗?我的意思是我不认为将对象分配给变量的人期望对象会改变......除非他们真的知道 PHP 会这样做...... 再一次:“通过引用传递”通常意味着通过某个地方。这只是常用词。 Tomalak 已经解释过——在第一种情况下,我们有一个副本。 对象的引用分配是非常混乱的!一个演员给你一个新的对象不是。 Alex,在 PHP 中,没有什么是永远通过引用传递(或通过引用分配),除非 PHP 被告知这样做。对象以 reference-like 方式处理(因为 object 的 zvals 只存储对对象数据的引用),但绝不是真正的引用。 【参考方案1】:问题出在这里:
$x = $foo;
$x = (object)array(5);
在第一条规则中,$x 被引用到 $foo;编辑 $x 也会编辑 $foo;(这称为“通过引用分配”,而不是“通过引用传递”*1)
$x->myProperty= "Hi";
将导致 $foo 也有一个属性“myProperty”。
但在下一行,您将 $x 引用到 new
对象。
有效地从 $foo 中取消引用 $x,您对 $x 所做的所有更改都不会传播到 $foo。
*1:当你调用一个函数时,你传递给函数的对象是(在php5中)“通过引用传递”
【讨论】:
好的,所以分配和通过引用都可以工作,但对我来说,如果没有 &,通过引用分配感觉“不自然”。如果我想要一个对象的副本怎么办:P 我阅读了其他正确答案,但仍然看不到我错过了什么。 +1 以获得清晰和简单的解释。 @Alex:你必须克隆它。 $copy = 克隆 $original;详情请见php.net/manual/en/language.oop5.cloning.php。 @Alex:我同意。 PHP 通过引用分配对象的策略让我的皮肤爬行。【参考方案2】:不仅对象是通过引用传递的; they are also assigned by reference(这就是你真正在说的):
在 PHP 中通常的按值赋值行为有一个例外,对象是在 PHP 5 中按引用分配的。
但是,在您的第一个示例中,您正在执行强制转换操作。 This entails a copy:
如果将任何其他类型的值转换为对象,则会创建 stdClass 内置类的新实例。
数组在 PHP 中有自己的类型,而不是对象;因此上述规则适用。
【讨论】:
是的,演员给了我们一份副本——而不是参考。但是主要OP的误解在于“通过引用传递”,这不在提供的代码中。 @gaRex:我知道。我不会说这是“主要”误解,但这肯定是一个因素。【参考方案3】:引用传递与赋值不同。
【讨论】:
简洁不能代替彻底。 我更喜欢给鱼而不是鱼。 -1 实际上,事实证明这是错误的。 PHP5 也通过引用来分配对象。 是的,你在写。但在这个具体的例子中这是不可能的。 @gaRex:不。引用分配发生得很好。让 OP 脱轨的是演员阵容。【参考方案4】:首先,您通过将数组转换为对象来创建对象。然后创建变量并通过引用传递该对象。但它不起作用,因为在那之后您将一些其他对象(从新数组转换)分配给第二个变量。
结果是对第二个对象的引用改变了,第一个对象本身没有改变。
查看Objects and References的更多详情。
【讨论】:
$foo
是一个数组,而不是一个对象。
啊,在演员阵容之后,当然。抱歉,来晚了。 “起初”它是一个数组,而不是一个对象。
@Tomalak 好的,我已经更改了答案,所以现在可能更清楚了。以上是关于通过引用传递;为啥原始对象没有改变?的主要内容,如果未能解决你的问题,请参考以下文章