我一直在玩这个愚蠢的问题大约一个小时了。以为我只是因为这么晚才工作而失去了大脑。
以下是一些代码:
foreach ( ..) {
if ($offer->device_code == 15) {
$offer->device_code = 2;
$offer_array[] = $offer;
$offer->device_code = 1;
$offer_array[] = $offer;
} else {
$offer_array[] = $offer;
}
}
$this->offer_array = $offer_array;
return true
在我看来,我希望在条件语句中复制device_code == 15的每个$ offer。所以我会在$ offer_array中提供两次,一次是device_code = 1,另一次是device_code = 2.
然而,
$offer->device_code = 1;
覆盖项
$offer->device_code = 2;
首先在$ offer_array中抛出的任何内容都会被覆盖。
有人可以解释为什么会这样吗?什么是解决问题的更好方法?
非常感谢。
答案 0 :(得分:3)
PHP通过引用分配对象,而不是按值分配。当您使用对象$offer
迭代循环并修改它以设置其device_code
时,将其附加到数组然后再次修改它并再次追加它,实际上是附加两个对同一个对象到您的阵列上。当您更改其中一个属性时,即使其中一个看起来已经附加到数组,也会更改它们的属性。
如果您希望最终得到两个不同的$offer
对象副本,则需要clone
它。
if ($offer->device_code == 15) {
$offer->device_code = 2;
$offer_array[] = $offer;
// Clone the object to an entirely new one
$cloned = clone $offer;
// and set its property then append to the array
$cloned->device_code = 1;
$offer_array[] = $cloned;
} else {
$offer_array[] = $offer;
}
// Make an object
$s = new stdClass;
// and an array
$a = [];
// Set some properties
$s->one = 1;
$s->two = 2;
// Stick it onto the array
$a[] = $s;
// Change a property and stick another onto the array
$s->two = 3;
$a[] = $s;
print_r($a);
// Oops, both of them have the new value $s->two = 3
Array
(
[0] => stdClass Object
(
[one] => 1
[two] => 3 <--- no longer 2
)
[1] => stdClass Object
(
[one] => 1
[two] => 3
)
)
// Clone one and change its property
$cloned = clone $s;
$cloned->two = 4;
$a[] = $cloned;
print_r($a);
// The clone retains its own property
// since it points to an entirely different object in memory
Array
(
[0] => stdClass Object
(
[one] => 1
[two] => 3
)
[1] => stdClass Object
(
[one] => 1
[two] => 3
)
[2] => stdClass Object
(
[one] => 1
[two] => 4 <-- doesn't affect the other references
)
)