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

PHP mysqli递归查询层级产品 如何限制含子产品的返回总数

实现层级产品列表总数限制的方案

你遇到的计数器失效问题,核心原因是递归调用时普通变量按值传递,各层递归的计数变量独立不共享,深层修改的计数无法同步到上层。以下两种方案都可以稳定实现最多返回8条全层级产品的需求:


方案1:最小改动修复现有PHP递归逻辑

只需要把计数变量改为引用传递,在每次输出、递归前判断是否达到数量上限即可,不需要调整原有输出结构,修改后的可运行代码如下:

function get_the_list($id = 0, $owner_id = 1, &$count = 0, $maxLimit = 8, $depth = 1) {
    $list = '';
    // 达到上限直接终止
    if ($count >= $maxLimit) return $list;

    // 数据库连接请替换为你自己的配置,这里用预处理避免SQL注入
    $conn = mysqli_connect("数据库地址", "账号", "密码", "库名");
    $stmt = mysqli_prepare($conn, "SELECT id, product_title, main_id FROM products WHERE main_id = ? AND owner_id = ?");
    mysqli_stmt_bind_param($stmt, "ii", $id, $owner_id);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);

    $loopI = 0;
    while ($row = mysqli_fetch_assoc($result)) {
        if ($count >= $maxLimit) break;
        $loopI++;
        $count++;
        // 保留原输出格式
        $list .= str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;", $depth-1) . "({$row['main_id']})   i: {$loopI} --- loop: {$count}, {$depth} - {$row['product_title']}<br>";
        // 注意:原代码递归传参有误,查当前产品的子级需要传当前行的id,而非main_id,否则会死循环
        $list .= get_the_list($row['id'], $owner_id, $count, $maxLimit, $depth+1);
    }
    mysqli_stmt_close($stmt);
    return $list;
}

// 初始化调用
$totalCount = 0;
echo get_the_list(0, 1, $totalCount);

该方案下计数变量全程全局共享,不会受递归深度影响,计数到8时会自动终止所有层级的查询和输出,和你预期的“查到Rearview mirror就终止”的逻辑完全一致。


方案2:SQL递归CTE一次性查询(推荐,性能更高)

如果你的数据库是MySQL 8.0+、PostgreSQL等支持递归CTE的版本,可以直接在SQL层完成层级遍历、排序、数量截断,不需要PHP层递归发多次查询,性能提升明显,SQL语句如下:

WITH RECURSIVE product_hierarchy AS (
    -- 锚点:查询所有顶级主产品
    SELECT id, product_title, main_id, 1 AS depth, CAST(id AS CHAR(200)) AS sort_path
    FROM products
    WHERE main_id = 0 AND owner_id = 1
    UNION ALL
    -- 递归:关联查询所有子产品
    SELECT p.id, p.product_title, p.main_id, ph.depth + 1 AS depth, CONCAT(ph.sort_path, '-', p.id)
    FROM products p
    JOIN product_hierarchy ph ON p.main_id = ph.id
    WHERE p.owner_id = 1
)
-- 按深度优先的遍历顺序排序,直接取前8条
SELECT * FROM product_hierarchy
ORDER BY sort_path
LIMIT 8;

查询结果直接返回按你原有层级顺序排列的8条产品,PHP端只需要一次查询拿到结果,遍历输出格式即可,完全不存在递归计数失效的问题。


内容的提问来源于stack exchange,提问作者Miedzegadze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:54:27