我有以下代码,显示PHP使用对象的最后一次迭代覆盖对象的Array元素。为什么会这样做呢?我想记录对象发生的事情,我使用数组来做到这一点。在我更改对象时查看数组的结果。为什么PHP会这样做。在我看来,它可能会导致严重的错误。即使使用其他人推荐的unset()也行不通。它只有在我取消设置ENTIRE对象时才有效。但是,如果只有1个元素发生变化,我为什么要这样做呢?如果我的对象中有10个元素,并且1个更改,我需要将ENTIRE对象复制到数组中。推理与我为什么需要这样做无关。我更感兴趣的是找出为什么PHP有这种行为。这是一个已知的错误吗?
<?php
$server->server = 'c17d7ae1-c298-4a1d-b7ee-2a3c9a2ab14d';
$servers['test1'] = $server;
print_r($servers);
unset($server->server); // <----- WHY DOES THIS NOT WORK?
$server->server = 'f88043af-dcf6-4802-a3d7-91cb594da4b0';
$servers['test2'] = $server;
print_r($servers);
?>
结果:
php test.php
Array
(
[test1] => stdClass Object
(
[server] => c17d7ae1-c298-4a1d-b7ee-2a3c9a2ab14d
)
)
Array
(
[test1] => stdClass Object
(
[server] => f88043af-dcf6-4802-a3d7-91cb594da4b0 <--- This right here is WRONG
)
[test2] => stdClass Object
(
[server] => f88043af-dcf6-4802-a3d7-91cb594da4b0
)
)
答案 0 :(得分:1)
将对象分配给另一个变量时,PHP不会复制该对象,而是创建一个引用。这意味着,两个变量现在指向同一个对象。
在您的代码中,首先设置属性server
。然后,您创建对$server
指向$servers[0]
的对象的引用。然后取消设置属性server
- 这确实可以正常工作。之后,你再次设置它 - 一个新值。接下来,在$servers[1]
中创建另一个引用。现在你有3个变量都指向同一个对象:$server
,$servers[0]
和$servers[0]
。
如果你真的想这样做(stdClass
es不应该用作动态对象,这是javascript的方式,虽然在PHP中有效但它与OOP范式相矛盾),使用{{ 1}}复制对象:
clone
答案 1 :(得分:0)
当你这样做时
$servers['test1'] = $server;
您已将$server
的引用保存到位置$servers
的{{1}}数组中。你对'test1'
做的任何事都不会影响数组中引用的内容,因为它们不是同一个东西。这就是你要做的事情:
$server
答案 2 :(得分:0)
unset()
取消设置变量 - a.o.t.取消一个变量来自的地方。
所以
$server->server = 'c17d7ae1-c298-4a1d-b7ee-2a3c9a2ab14d';
$servers['test1'] = $server;
unset($server->server); //THIS DOES WORK - BUT IT IS NOT WHAT YOU WANT
unset($servers['test1']); //NEW: THIS DOES WHAT I THINK YOU WANT