Laravel递归函数仅返回直接子分类ID问题排查
问题分析与解决方法
你的递归函数只返回直接子分类ID,核心原因是PHP数组默认是值传递:调用subCategoriesList($child->id, $data)时,传递的是$data的副本,子函数里添加的孙分类及更深层级的ID不会同步到父函数的$data中,最终只有直接子分类被保留。
下面给出两种修复方案:
方案1:使用引用传递参数
把$data参数改为引用传递,让子函数对数组的修改直接作用于父函数的变量:
function subCategoriesList($id, &$data=[]){ $children = Category::whereParentId($id)->get(); foreach ($children as $child){ $data[] = $child->id; subCategoriesList($child->id, $data); } return $data; }
参数前的&符号表示将$data以引用方式传递,递归时所有层级的子分类ID都会被存入同一个数组。
方案2:合并递归返回的结果
不使用引用,而是将每次递归返回的子分类ID数组合并到当前$data中:
function subCategoriesList($id, $data=[]){ $children = Category::whereParentId($id)->get(); foreach ($children as $child){ $data[] = $child->id; // 合并子函数返回的深层子分类ID $data = array_merge($data, subCategoriesList($child->id)); } return $data; }
每次递归调用后,用array_merge把返回的结果追加到当前数组,实现所有层级ID的累积。
额外优化(Laravel专属)
如果是在Laravel框架中,推荐用Eloquent的递归关联来实现,代码更简洁易维护:
首先在Category模型中定义递归关联:
class Category extends Model { // 定义直接子分类关联 public function children() { return $this->hasMany(Category::class, 'parent_id'); } // 定义所有层级子分类的递归关联 public function allChildren() { return $this->children()->with('allChildren'); } }
然后获取指定分类下所有子分类ID:
$category = Category::find($id); $allChildIds = $category->allChildren()->get()->pluck('id')->toArray();
内容的提问来源于stack exchange,提问作者Kemal Özvarol
相关产品推荐
相关产品推荐

