PHP分类递归无法获取全部子分类ID数组问题求助
问题
分类系统支持多级分类,父分类可包含多个子分类,子分类也可继续拥有子分类。编写脚本根据选中的分类ID,将其所有层级的子分类ID存入数组时,递归输出所有子分类ID正常,但最终数组仅能保存第一级子分类ID,无法获取全部层级的子分类ID。
分类数据库结构
cat_id cat_name cat_parent_id 123 parent1 0 456 child1 123 789 child2 123 101112 child3 123 131415 childa1 456 161718 childa2 456 192021 childb1 789 222324 childb2 789
当前代码
$childCatsArray = array(); $catsArray = hasChildren($catID, $childCatsArray); function hasChildren($catID, $array) { global $conn; $sql = "SELECT * FROM `SysCategories` WHERE `cat_parent_id` = ?;"; $stmt = mysqli_stmt_init($conn); // bind integer value $parent_id if(!mysqli_stmt_prepare($stmt, $sql)){ echo 'SQL ERROR 2'; return; } mysqli_stmt_bind_param($stmt, "s", $catID); mysqli_stmt_execute($stmt); $resultData = mysqli_stmt_get_result($stmt); while($child = mysqli_fetch_assoc($resultData)){ $child_cat_id = $child['cat_id']; $child_cat_name = $child['cat_name']; array_push($array, $child_cat_id); hasChildren($child_cat_id, $array); } return $array; }
问题现象
返回的数组仅包含第一级子分类:
Array ( [0] => 123 [1] => 456 [2] => 789 [3] => 101112 )
解决方法
问题核心是PHP数组默认的值传递机制:递归调用函数时,传递的是数组副本,修改副本不会影响原数组,导致深层级的子分类ID无法存入初始数组。需改成引用传递,让递归函数直接操作同一个数组。
修改步骤
- 修改函数参数,在
$array前添加&符号,声明为引用传递:function hasChildren($catID, &$array) { } - 可选优化:移除函数末尾的
return $array;,因为引用传递会直接修改外部传入的数组,无需返回(保留也不影响,但更简洁)。
修改后的完整代码
$childCatsArray = array(); hasChildren($catID, $childCatsArray); // 直接调用,结果会存入$childCatsArray function hasChildren($catID, &$array) { global $conn; $sql = "SELECT * FROM `SysCategories` WHERE `cat_parent_id` = ?;"; $stmt = mysqli_stmt_init($conn); if(!mysqli_stmt_prepare($stmt, $sql)){ echo 'SQL ERROR 2'; return; } mysqli_stmt_bind_param($stmt, "i", $catID); // 若cat_parent_id是整数,用"i"更严谨 mysqli_stmt_execute($stmt); $resultData = mysqli_stmt_get_result($stmt); while($child = mysqli_fetch_assoc($resultData)){ $child_cat_id = $child['cat_id']; array_push($array, $child_cat_id); hasChildren($child_cat_id, $array); // 递归调用时操作同一个数组 } }
补充说明
- 引用传递的作用是让函数内部对数组的修改直接作用于外部传入的数组,而非创建副本,确保所有层级的子分类ID都能被添加到同一个数组中。
- 若
cat_parent_id字段类型为整数,将mysqli_stmt_bind_param的类型参数从s改为i,更符合数据类型规范。
内容的提问来源于stack exchange,提问作者Snappysites
相关产品推荐
相关产品推荐

