You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:45:41