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

PHP递归函数实现家族谱系查询:如何避免使用全局变量

解决方案

方案1:使用引用参数传递结果数组

给函数增加一个引用类型的可选参数,所有递归调用都操作同一个数组实例,完全避免全局变量污染。

function checkForChildren($uuid, $conn, &$familyArray = []){
    $sql = "SELECT id, uuid, name FROM people WHERE parent = '".$uuid."'";
    $result = mysqli_query($conn, $sql);
    
    if (mysqli_num_rows($result) > 0){
        foreach ($result as $row){
            $familyArray[]= [
                'id' => $row['id'],
                'uuid' => $row['uuid'],
                'name' => $row['name']
            ];                
            checkForChildren($row['uuid'], $conn, $familyArray);
        }
    }
    return $familyArray;
}

调用时不需要传第三个参数,函数会自动初始化空数组:$allDescendants = checkForChildren('0001', $conn);

方案2:纯函数实现(无引用、无额外参数)

每次递归调用返回当前节点的所有后代数组,把当前层级的子节点和子节点的递归结果合并后返回,完全无外部依赖,无副作用。

function checkForChildren($uuid, $conn){
    $familyArray = [];
    $sql = "SELECT id, uuid, name FROM people WHERE parent = '".$uuid."'";
    $result = mysqli_query($conn, $sql);
    
    if (mysqli_num_rows($result) > 0){
        foreach ($result as $row){
            // 先加入当前层级的子节点
            $familyArray[]= [
                'id' => $row['id'],
                'uuid' => $row['uuid'],
                'name' => $row['name']
            ];                
            // 合并当前子节点的所有后代
            $familyArray = array_merge($familyArray, checkForChildren($row['uuid'], $conn));
        }
    }
    return $familyArray;
}

额外优化建议

  • 现有SQL直接拼接UUID参数存在SQL注入风险,建议改为mysqli预处理语句查询,示例如下:
$stmt = mysqli_prepare($conn, "SELECT id, uuid, name FROM people WHERE parent = ?");
mysqli_stmt_bind_param($stmt, "s", $uuid);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
  • 如果数据量较大,递归查询会产生多次数据库请求,性能较低,可以考虑一次性查询全表后在PHP内存中构建树结构再提取后代,减少数据库IO开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:45:07