PHP会覆盖数组元素吗?

时间:2014-02-04 23:57:42

标签: php arrays object

我有以下代码,显示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
        )

)

3 个答案:

答案 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