Php 如何将递归函数与另一个参数组合
我有一个递归工作的脚本,能够显示多层次的子菜单。问题是:目前我的CMS中有两个部分 类别和文章 文章可以在类别下,类别可以在其他类别(子类别)下,但文章不能在其他文章下 目前,我的脚本仅适用于类别,但如果我的CMSPhp 如何将递归函数与另一个参数组合,php,function,recursion,Php,Function,Recursion,我有一个递归工作的脚本,能够显示多层次的子菜单。问题是:目前我的CMS中有两个部分 类别和文章 文章可以在类别下,类别可以在其他类别(子类别)下,但文章不能在其他文章下 目前,我的脚本仅适用于类别,但如果我的CMS文章1和类别1都在类别0下,我想显示它们,而不仅仅是类别1 在我的数据库中,结构如下所示: `snm_categories` - contains category data `id` - the id of a category parent_id - the id of it's
文章1
和类别1
都在类别0
下,我想显示它们,而不仅仅是类别1
在我的数据库中,结构如下所示:
`snm_categories` - contains category data
`id` - the id of a category
parent_id - the id of it's parent category, this is `1` if it has no parent
`snm_content` - contains the article data
`catid` - the id of the category it falls under, in my above example this will be the same id as the parent_id of `category1`
这是我的剧本:
<?PHP
// Get all categories and articles
$menu = "
SELECT cat.id as cat_id, cat.level, cat.parent_id, cat.title as cat_title, cat.alias as cat_alias, cat.published, cat.rgt, cnt.state, cnt.id as content_id, cnt.catid, cnt.title as content_title, cnt.alias as content_alias
FROM snm_categories cat
LEFT JOIN snm_content cnt
ON cnt.catid = cat.id
WHERE cat.id NOT IN (1, 2, 3, 4, 5, 7, 8, 22)
AND cat.published = 1
GROUP BY cat.id
ORDER BY cat.rgt ASC";
$menuconn = $conn->query($menu);
// Create new array
$menuData = array(
'items' => array(),
'parents' => array()
);
// Create new array with `items` and `parents`, which contain cat_id and parent_id
while($menu = $menuconn->fetch_assoc())
{
$menuData['items'][$menu['cat_id']] = $menu;
$menuData['parents'][$menu['parent_id']][] = $menu['cat_id'];
}
// Function to create menu, $parentId is 1 (when categories have no parent and are topcategories)
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]))
{
// If parent_id is 1 put a <li> around it (because it's not a subcat) if not put an <ul> around
if($parentId == '1'){
$html = '<li>';
}else{
$html = '<ul class="sub-menu">';
}
foreach ($menuData['parents'][$parentId] as $itemId)
{
$html .= '<li class="menu-item"><a href="info/'.$menuData['items'][$itemId]['cat_alias'].'">'.$menuData['items'][$itemId]['cat_title'].'</a>';
// Use this function recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
if($parentId == '1'){
$html .= '</li>';
}else{
$html .= '</ul>';
}
}
return $html;
}
// Echo menu
echo buildMenu(1, $menuData);
?>
我看到的第一个问题是在下面的代码中
while($submenu=$submenucon->fetch\u assoc()){
$artikelsubs='';
}
如果有10篇文章,您是否存储最后一篇?此外,由于某些原因,您没有结束li
标记
因为我没有DB来检查这一点,但根据我的理解,循环应该如下所示
while($submenu=$submenucon->fetch\u assoc()){
$artikelsubs.=';
}
此外,如果文章列表基于cat\u id
,那么您也应该存储这些数据
$menuData['articles'][$menu['cat_id']]=$artikelsubs;
并确保在内部while循环之前清空artikelsubs
。那你需要
替换$html.=$artikelsubs
从菜单数据
对象中获取它我看到的第一个问题是在下面的代码中
while($submenu=$submenucon->fetch\u assoc()){
$artikelsubs='';
}
如果有10篇文章,您是否存储最后一篇?此外,由于某些原因,您没有结束li
标记
因为我没有DB来检查这一点,但根据我的理解,循环应该如下所示
while($submenu=$submenucon->fetch\u assoc()){
$artikelsubs.=';
}
此外,如果文章列表基于cat\u id
,那么您也应该存储这些数据
$menuData['articles'][$menu['cat_id']]=$artikelsubs;
并确保在内部while循环之前清空artikelsubs
。那你需要
替换$html.=$artikelsubs
从菜单数据
对象获取它我知道这与您的代码非常不同,但我在几周前为类似的情况编写了这篇文章,因此我对它进行了一些调整,以适应您的情况:
<?php
echo get_items(1);
function get_items($id){
global $conn; //db connection object
$html = '';
$sql = mysqli_query($conn, "SELECT * FROM snm_content WHERE catid = $id");
while($row = mysqli_fetch_assoc($sql)){
$html .= '<li>'.$row['title'].'</li>';
}
$sql = mysqli_query($conn, "SELECT * FROM snm_categories WHERE parent_id = $id");
while($row = mysqli_fetch_assoc($sql)){
$html .= '<li>'.$row['title'].'
<ul>'.get_items($row['id']).'</ul>
</li>';
}
return $html;
}
?>
我认为您可以轻松地修改它,以获得所需的确切html标记,但其本质是存在的。如果你对此有任何疑问,请不要犹豫
顺便说一下,我使用了与您相同的DB结构,在snm_内容和snm_类别中输入了一些行,这是我得到的输出:
第0类
- 第0条
- 第一类
- 第一条
- 第二条
- 第2类
- 第三条
第3类
- 第四条
我知道这与您的代码非常不同,但我在几周前为类似的情况编写了此代码,因此我对其进行了一些调整,以适应您的情况:
<?php
echo get_items(1);
function get_items($id){
global $conn; //db connection object
$html = '';
$sql = mysqli_query($conn, "SELECT * FROM snm_content WHERE catid = $id");
while($row = mysqli_fetch_assoc($sql)){
$html .= '<li>'.$row['title'].'</li>';
}
$sql = mysqli_query($conn, "SELECT * FROM snm_categories WHERE parent_id = $id");
while($row = mysqli_fetch_assoc($sql)){
$html .= '<li>'.$row['title'].'
<ul>'.get_items($row['id']).'</ul>
</li>';
}
return $html;
}
?>
我认为您可以轻松地修改它,以获得所需的确切html标记,但其本质是存在的。如果你对此有任何疑问,请不要犹豫
顺便说一下,我使用了与您相同的DB结构,在snm_内容和snm_类别中输入了一些行,这是我得到的输出:
第0类
- 第0条
- 第一类
- 第一条
- 第二条
- 第2类
- 第三条
第3类
- 第四条
您正在覆盖内部和外部while循环中的artikelsubs
?文章可以在类别下?您的查询是否返回所有文章?我认为使用left-join时,每个类别只有一个连接。虽然可能有关联,但如果您完全控制了数据库,您可以添加列;我建议您为您的类别实现嵌套集模型。您正在覆盖内部和外部循环中的artikelsubs
,而这两个循环都是?文章可以在类别下?您的查询是否返回所有文章?我认为使用left-join时,每个类别只有一个连接。虽然可能有关联,但如果您完全控制了数据库,您可以添加列;我建议您为您的类别实现嵌套的集合模型。很好的捕获,完全检查了
。所以我用你的代码替换了它,但是你的最后一部分我并不完全清楚:那么你需要替换你的$html。=$artikelsubs;要从menuData对象获取它,我需要创建另一个循环吗?我的意思是你需要使用$html.=$menuData['articles'][$parentId]
,但这也可能看起来是错误的,因为你只在$parentId==“1”
时才这样做,所以你需要想好如何使用good catch,彻底检查一下
。所以我用你的代码替换了它,但是你的最后一部分我并不完全清楚:那么你需要替换你的$html。=$artikelsubs;要从menuData对象获取它,是否需要创建另一个循环?我的意思是您需要使用$html.=$menuData['articles'][$parentId]
,但这似乎也是错误的,因为您只在$parentId==“1”
时才这样做,所以您需要考虑使用什么