PHP 递归函数 - 如何避免使用全局变量

Posted

技术标签:

【中文标题】PHP 递归函数 - 如何避免使用全局变量【英文标题】:PHP Recursive Function - How To Avoid Using A Global Variable 【发布时间】:2022-01-07 18:11:48 【问题描述】:

我创建了一个函数,该函数为所选父级的后代返回一个数据数组。

首先,它检查我们已为其提供 UUID 的父级的子级,然后检查这些子级的其他子级,依此类推,最终返回所选父系谱系中所有用户的数组。

    Example of my DB Table
    **id, name, uuid, parent**
    1, John, 0001, none
    2, Steve, 0002, 0001
    3, Mark, 0003, 0001
    4, Kevin, 0004, 0002
    5, Adam, 0005, 0003

    function checkForChildren($uuid, $conn)
        global $familyArray;
    
        $sql = "SELECT id, uuid, name FROM people WHERE parent = '".$uuid."'";
        $result = mysqli_query($conn, $sql);
        
        /*-- Data has been found --*/
        if (mysqli_num_rows($result) > 0)
            foreach ($result as $row)
                $familyArray[]= 
                [
                    'id' => $row['id'],
                    'uuid' => $row['uuid'],
                    'name' => $row['name']
                ];                
                checkForChildren($row['uuid'],$conn);
            
        
        return $familyArray;
    

代码工作正常 $familyArray 作为一个全局变量,但我已经明白使用全局变量不是一个好习惯。

没有 $familyArray 是全局的,该函数不再返回完整的家族血统,只返回我们最初输入函数的父 $uuid 的直系后代。

有没有人知道如何在没有全局数组的情况下完成这项工作?

提前致谢。

【问题讨论】:

【参考方案1】:

您可以从递归调用返回数组结果,并在父级调用中将它们合并。

<?php

function checkForChildren($uuid, $conn)
    $familyArray = [];

    $sql = "SELECT id, uuid, name FROM people WHERE parent = '".$uuid."'";
    $result = mysqli_query($conn, $sql);

    foreach ($result as $row)
        $familyArray[] = [
            'id' => $row['id'],
            'uuid' => $row['uuid'],
            'name' => $row['name']
        ];                
        $familyArray = array_merge($familyArray,checkForChildren($row['uuid'],$conn));
    

    return $familyArray;

更新:

我建议您查看with recursive cte 查询,以避免通过数据库查询调用到数据库服务器来回往返。

【讨论】:

谢谢!在过去的 8 个小时左右,我一直在修补解决方案。这非常有效。非常感谢您的帮助。我注意到您删除了检查是否返回了 1 行或更多行数据,这是因为“foreach ($result as $row)”不会从 NULL 触发吗?再次感谢你!你刚刚添加了一小股纤维,有朝一日它会成为我正在尝试雕刻的弓上的一根绳子,哈哈。 :thumbup: @LearningLanguages 没问题。我们都在那里花费数小时试图找出问题及其解决方案。只是不要放弃。是的,我删除了 if 条件检查,假设 foreach 也会处理 $result 的空数组结果。你可以var_dump($result) 来检查每次返回的内容。如果 if 条件导致从 MySQL 返回的空行出现问题,您可以恢复它。 感谢您的解释 =) 没有 if 条件应该没问题,因为我使用数组长度作为后代的总数,所以我可以在显示家谱的实际个人资料页面。再次感谢你!现在我的项目根本不使用全局变量 =) @LearningLanguages 很高兴听到这个消息。如果$uuid 来自前端,则需要使用准备好的语句来保证安全。全局变量大多不好,但有时很有用,例如,整个应用程序的单个全局 $app 实例。甚至 wordpress 也为我们提供了一个 $wpdb 全局 DB 变量来使用。但是,是的,在您的情况下,避免它们是一种好方法。

以上是关于PHP 递归函数 - 如何避免使用全局变量的主要内容,如果未能解决你的问题,请参考以下文章

团队合作-如何避免JS冲突

函数(局部变量与全局变量,函数即变量理论,递归函数)

将带有全局变量的递归转换为使用堆栈的迭代

在C语言中啥是全局变量?用一个小程序段说明下,谢谢,

python基础 函数局部变量 全局变量 递归

Python函数:全局变量和局部变量匿名函数lambda递归函数