在某些第三方代码中,我不允许更改,发生了一些奇怪的事情。
他们将一个变量(包含对象的数组)写入会话(不进行序列化),然后使用foreach对原始变量进行迭代(不使用引用)。每当他们更改值时,会话中的相应值也会更改。我能够创建一个具有相同行为的小示例:
$ test = array((object)array(“categories”=>“test”));
$ _ SESSION ['woot'] = $ test;
的print_r($ _ SESSION [ '活泉']);
foreach($ test as $ a){
if (!is_array($a->categories)) $a->categories = array();
}
的print_r($ _ SESSION [ '活泉']);
结果如下:
Array
(
[0] => stdClass Object
(
[categories] => test
)
)
Array
(
[0] => stdClass Object
(
[categories] => Array
(
)
)
)
我已经注意到,当我序列化和反序列化对象数组时,问题不会发生。
有没有人知道这里发生了什么?这是代码吗?这是不正确的服务器设置吗?在我联系代码开发人员之前,我想了解一点。
其他信息:
此致 Joost的。
答案 0 :(得分:3)
仅包含对象holds a reference to that object的变量。将对象(对象引用)从一个变量分配给另一个变量不会创建对象的副本,仍然只有一个对象。如果修改该对象,则所有包含对该对象的引用的变量都将看到更改,因为只有一个对象实例。
如果要制作对象的副本,则需要明确clone
它。
答案 1 :(得分:1)
在PHP对象中passed by reference,PHP使用copy-on-write。
$test = array((object)array("categories" => "test"));
// it is still the same array
$_SESSION['woot'] = $test;
foreach ($test as $a) {
// You change something in an object, which is passed by reference
if (!is_array($a->categories)) $a->categories = array();
}
序列化和反序列化会创建新对象
$test = array((object)array("categories" => "test"));
// new array with new objects
$test = unserialize(serialize($test));