Php 如何查找没有父页面的页面?
我有一个父/子结构,在这个结构中,可以删除父/子结构,并且它的子结构仍将在数据库中。如果发生这种情况,最低的父级应设置为0的父级 我被这个问题困住了,因为我不确定如何构造我的(可能是递归的)循环 我需要返回一个父项不存在的页面ID数组;示例:Php 如何查找没有父页面的页面?,php,loops,parent-child,Php,Loops,Parent Child,我有一个父/子结构,在这个结构中,可以删除父/子结构,并且它的子结构仍将在数据库中。如果发生这种情况,最低的父级应设置为0的父级 我被这个问题困住了,因为我不确定如何构造我的(可能是递归的)循环 我需要返回一个父项不存在的页面ID数组;示例:数组(5,9,8) 这是我的数据集,结构可以通过父id连接;我们可以看到,页面ID 8和9具有不存在的7的父项: evar_export($orphans($pages)); $data = array ( 0 => array (
数组(5,9,8)
这是我的数据集,结构可以通过父id连接;我们可以看到,页面ID 8和9具有不存在的7的父项:
evar_export($orphans($pages));
$data = array (
0 => array (
'id' => 1,
'url' => 'Home-Page',
'parent' => 0
),
1 => array (
'id' => 2,
'url' => 'page1',
'parent' => 1
),
4 => array (
'id' => 5,
'url' => 'page4',
'parent' => 4
),
5 => array (
'id' => 6,
'url' => 'page5',
'parent' => 5
),
6 => array (
'id' => 8,
'url' => 'no-parent-1',
'parent' => 7
),
7 => array (
'id' => 9,
'url' => 'no-parent-2',
'parent' => 7
)
);
我尝试过递归,但不知道如何捕捉子树的结尾:
$orphans = function($array, $temp = array(), $index = 0, $parent = 0, $owner = 0) use(&$orphans) {
foreach ($array as $p) {
if($index == 0) {
$owner = $p['id'];
}
if ($index == 0 || $p['id'] == $parent) {
$temp[] = $p['id'];
$result = $orphans($array, $temp, $index + 1, $p['parent'], $owner);
if (isset($result)) {
return $result;
}
}
else {
return $temp;
}
}
};
我将此示例中的数据数组命名为“pages”:
$orphans = array();
foreach($pages as $p)
{
if($p['parent'] == 0)
continue; //End this iteration and move on.
$id = $p['id'];
$parent = $p['parent'];
$parentExists = false;
foreach($pages as $p2)
{
if( $p2['id'] == $parent )
{
$parentExists = true;
break; //Found, so stop looking.
}
}
if(!$parentExists)
{
$orphans[] = $id;
}
}
如果在运行此操作后var_转储$孤儿数组,您将得到:
array(2) {
[0]=>
int(8)
[1]=>
int(9)
}
这似乎是理想的结果。不幸的是,在foreach中嵌套另一个foreach是必需的,除非您修改数据结构,以使id成为键(我建议您减少资源使用以处理此问题)。使用continue/break控件结构至少会限制使用
关于嵌套Foreach的澄清
理想的数据结构将在顺序项上使用键值对,特别是在处理动态数据时,因为键是未知的。以您的数据为例,获取第四项的URL很容易:
$id = $pages[4]['id'];
但第4项和相关数据之间没有关系/逻辑关联。它的顺序是基于曾经构建的数据。相反,如果将id指定为键,则我们可以轻松找到id为4的页面的父id:
$parent = $pages[4]['parent'];
因此,在对数据进行简单解析以查找不存在的父项时,您只需执行以下操作:
foreach($pages as $p)
{
if($p['parent'] == 0)
continue; //End this iteration and move on.
$id = $p['id'];
if(! isset($pages[$p['parent']])
{
$orphans[] = $id;
}
}
因为这样我们就可以确定密钥是id,然后以这种方式对数据进行逻辑处理。考虑到像页面id这样的东西是主键(非重复),这应该是完全可能的
但是在数组中的键和值之间没有逻辑关联的情况下,我们必须查看整个数据集,以便为每次迭代找到匹配项,从而导致资源使用量呈指数级增长,以完成任务。太好了,那么您尝试了什么?@Darren:我尝试了递归函数。但我不能让它工作。我在帖子中添加了代码。嗯,这很有效,所以你肯定能接受!我不明白为什么每个循环都需要另一个嵌套循环?在什么情况下需要这样做?嵌套的foreach循环在原始循环的每次迭代中都会在同一数组上重新循环以查找所需的父值。因此,包含8项的原始数组会导致64个潜在循环。例如,一个包含100个项目的数组将导致10000个潜在循环。所以你可以明白为什么避免这样做是理想的。我会调整我的答案来解释原因。我感谢你的帮助。这很有意义。谢谢我能做的最好的事情,就是在管理实际页面时运行这个,我想,这将减少对这个函数的需求。