如果是tl; dr:使用引用设置数组,然后更改所述数组的副本仍然保留引用,并且同时更改所有副本的元素。需要使用它指向的值替换引用的解决方法。
我在使用PHP数组中的引用时遇到了一个复杂的问题:(
我有一个具有两个属性的独特元素的平面数组:顺序和级别。 Order在类似目录方式中表示元素的顺序号从1到n。级别表示元素的“子章节”级别。
实施例: 第一个括号是随机但唯一的元素ID:
[1][order:1][level:1]
----[7][order:2][level:2]
----[4][order:3][level:2]
---- ----[2][order:4][level:3]
[3][order:5][level:1]
[6][order:6][level:1]
----[5][order:7][level:2]
.
.
.
请记住,这是一个扁平的元素数组,高于它的视觉表现。 现在我试图将它们放入表格阵列中:
[1][children] => [
[7],
[4][children] => [
[2]
]
]
[3],
[6][children] => [
[5]
]
哪个代表树结构-ish ..
我首先按顺序排序:
foreach($elements as $element){
$ordered_elements[$element['order']] = $element;
}
然后我将每个元素移到正确的父元素下面:
foreach($ordered_elements as &$child){
if($child['level'] > 1){
$ordered_elements[$last_parent[$child['level']-1]]['children'][$child['content_id']] = &$child; // I think this is problematic line!!!
}
$last_parent[$child['level']] = $child['sort_order'];
}
一些元素保留在根(第一)级别,不应该存在:
foreach($ordered_elements as &$child){
if($child['level'] == 1){
$ordered_elements[$child['content_id']] = $child;
}
unset($ordered_elements[$child['sort_order']]);
}
完成此操作后,模板阵列就绪。现在我开始使用element_id和user_id从查询中获取一些数据。
我想设置一个新表“users”,它将为每个用户创建此先前生成的数组,并且我将能够为每个用户更改其元素。
users[1]['elements'] = $ordered_elements;
users[2]['elements'] = $ordered_elements;
此函数应该从用户自己的元素池中按引用返回元素,因此我们可以将其直接更改为用户[x] ['elements'] [x]:
function &get_element_from_array(&$array, $searchValue){
$status = false;
foreach($array as $id => &$subtree) {
if ($id === $searchValue) {
return $subtree;
}
if (isset($subtree['children'])) {
$subsearch = &$this->get_element_from_array($subtree['children'], $searchValue);
if ($subsearch != false) {
return $subsearch;
}
}
}
return $status;
}
这意味着如果我想从用户2更改元素5,我需要像这样调用它:
$element = &get_element_from_array(users[2]['elements'], 5);
$element['visited'] = true;
这就是出现问题的地方:我刚刚在user2和user1数组元素中更改了这个元素。
我希望我写这篇文章的时间太长了,还有很好的解释。