
本文介绍使用递归函数实现无限级分类目录的 html 渲染,通过 mysql 查询与缩进样式动态展示任意深度的父子关系结构,避免嵌套循环硬编码,提升可维护性与扩展性。
本文介绍使用递归函数实现无限级分类目录的 html 渲染,通过 mysql 查询与缩进样式动态展示任意深度的父子关系结构,避免嵌套循环硬编码,提升可维护性与扩展性。
在构建内容管理系统(CMS)、电商网站或知识库时,常需展示具有树状结构的分类目录(如“电子产品 → 手机 → 智能手机 → 国产旗舰”)。传统多层 while 循环难以应对未知深度,而递归是解决此类问题的标准方案。
核心思路是:对每个节点,先输出自身,再以其 ID 为父 ID 查询并递归处理所有子节点。配合缩进参数(如 text-indent),即可直观呈现层级关系。
以下为完整、安全、可复用的实现代码:
<?php function outputCategory($conn, $parent_id = 0, $indent = 0) {
// 使用预处理语句防止 SQL 注入,绑定整型参数
$sql = "SELECT cat_id, cat_name FROM categories WHERE cat_parent_id = ? ORDER BY cat_name ASC";
$stmt = mysqli_prepare($conn, $sql);
if (!$stmt) {
error_log("SQL prepare failed: " . mysqli_error($conn));
return;
}
mysqli_stmt_bind_param($stmt, "i", $parent_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($result)) {
$cat_id = (int)$row['cat_id'];
$cat_name = htmlspecialchars($row['cat_name'], ENT_QUOTES, 'UTF-8');
// 每级缩进 20px,增强视觉层次
echo "<h3 style=\"margin: 4px 0; text-indent: {$indent}px;\">{$cat_name}";
// 递归调用:以当前分类 ID 为新 parent_id,缩进增加 20px
outputCategory($conn, $cat_id, $indent + 20);
}
mysqli_stmt_close($stmt);
}
// 启动递归:从根节点(cat_parent_id = 0)开始
outputCategory($conn);
?>
✅ 关键优化说明:
- ✅ 安全性:全程使用
mysqli_prepare()+bind_param(),杜绝 SQL 注入风险; - ✅ 健壮性:对
$row['cat_name']进行htmlspecialchars()转义,防止 XSS; - ✅ 可读性:
$indent参数控制缩进,无需手动维护多级<h3></h3>标签样式; - ✅ 可扩展性:函数签名支持传入
$conn,避免依赖全局变量(推荐做法); - ✅ 性能提示:若分类量极大(>5000 条),建议结合缓存(如 Redis)或改用闭包表(Closure Table)模型优化查询。
⚠️ 注意事项:
- 确保数据库中
cat_parent_id字段对根节点统一设为0(而非NULL),否则需调整 WHERE 条件(如IS NULL OR cat_parent_id = ?); - 递归深度受 PHP
xdebug.max_nesting_level或memory_limit限制,常规分类树(≤10 层)无压力; - 如需生成带链接的导航菜单,可在
echo中加入<a href="/category/%7B%24cat_id%7D"></a>; - 若需获取完整路径(如 “Parent > Child > Grandchild”),可在递归中传递并累积路径数组。
该方案以简洁、安全、符合现代 PHP 实践的方式,彻底解决多级分类动态渲染难题——一次编写,终身适配任意深度结构。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











