php - 循环到子级的 FINITIE 深度

标签 php mysql

我正在制作一个图片库,需要一些循环类别方面的帮助。下一个深度是图库配置文件中的已知设置,因此这不是关于无限深度循环的问题,而是循环已知深度并输出所有结果的最有效方法。

本质上,我想创建一个 <select>包含系统中定义的所有类别的框,包括子、孙等。

类别存储在数据库中,如下所示(还有其他字段,但它们不相关):

+----+--------+--------------+
| id | parent |     name     |
+----+--------+--------------+
|  1 |    0   | Parent 1     |
|  2 |    1   | Child Lvl  1 |
|  3 |    2   | Child Lvl 2  | 
|  4 |    0   | Parent 2     |
+----+--------+--------------+

任何具有 parent 的类别== 0 本身被视为顶级父级。正如我已经提到的,最大深度是已知的并且是预先确定的,所以我想输出如下所示的内容:

Parent 1
  - Child Lvl 1
    - Child Lvl 2
Parent 2

我原以为这是可能的 while循环,但由于某种原因这会导致 PHP 进入无限循环。

这是我迄今为止尝试过的代码:

$sql = $_database->prepare("SELECT `id`, `name` FROM `".TBL_PREFIX."categories` WHERE `parent` = '0' ORDER BY `name` ASC");
$sql->execute();
while($cat = $sql->fetchObject())
{
    $html.= "\n\t".'<option value="'.$cat->id.'"';
    $html.= (array_key_exists('selected_val', $options) && $options['selected_val'] == $cat->id) ? ' selected="selected"' : '';
    $html.= (array_key_exists('disabled_vals', $options) && in_array('', $options['disabled_vals'])) ? ' disabled="disabled"' : '';
    $html.= '>'.$cat->name.'</option>';

    $childSql = $_database->prepare("SELECT COUNT(*) AS `total` FROM `".TBL_PREFIX."categories` WHERE `parent` = :parent");
    $childSql->execute(array(':parent' => $cat->id));

    $numChildren = $childSql->fetchObject();
    $numChildren = $numChildren->total;
    $parentId = $cat->id;

    while($numChildren > 0)
    {
        for($i = 0; $i < (MAX_CAT_DEPTH - 1); $i++)
        {
            $children = $_database->prepare("SELECT `id`, `name` FROM `catgeories` WHERE `parent` = :parent ORDER BY `name` ASC");
            $children->execute(array(':parent' => $parentId));

            while($child = $children->fetchObject())
            {
                $html.= "\n\t".'<option value="'.$child->id.'"';
                $html.= (array_key_exists('selected_val', $options) && $options['selected_val'] == $child->id) ? ' selected="selected"' : '';
                $html.= (array_key_exists('disabled_vals', $options) && in_array('', $options['disabled_vals'])) ? ' disabled="disabled"' : '';
                $html.= '>'.$child->name.'</option>';

                $parentId = $child->id;

                $childSql = $_database->prepare("SELECT COUNT(*) AS `total` FROM `".TBL_PREFIX."categories` WHERE `parent` = :parent");
                $childSql->execute(array(':parent' => $parentId));
                $numChildren = $childSql->fetchObject();
                $numChildren = $numChildren->total;
            }
        }
    }
}

任何人都可以建议正确的方式来解决这个问题。我不想过多地使用数据库结构,因为我相信我已经拥有的数据库结构足以满足这里的要求 - 这不是一个像其他问题一样关于无限深度的问题。

最佳答案

丑陋地尝试使用 mptt 算法来避免递归语句。 Zebra MPTT 这是一个很好的解决方案。 Gedmo 树更好。

关于php - 循环到子级的 FINITIE 深度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19847038/

相关文章:

php - 如何将逗号分隔的列转换为行并添加计数器

php - POST 数据未出现在 CakePHP Controller 中

mysql - 连接mysql和tomcat?

带有两个时间戳的 PHP If 语句

javascript - HTML 表单 JS 验证

php - 如何隐藏 "Deprecated: mysql_connect()"警告?

php - phpmyadmin中创建函数错误

mysql - 当子查询匹配时更新表

php - 根据用户类型重定向到另一个页面

mysql - nix-shell --命令 `stack build` 导致 libpq-fe.h : No such file or directory