【问题标题】:Recursive PHP function is not returning expected value递归PHP函数未返回预期值
【发布时间】:2013-02-24 01:51:48
【问题描述】:

我正在尝试创建一个函数,该函数将为存储在数据库中的每个用户创建一个唯一的用户名。

我的计划是通过连接名字和姓氏来创建一个用户名,然后检查是否使用了这个用户名。如果不只是将其存储在数据库中,如果是,则在其末尾添加一个数字。

例如,如果使用 ConnorAtherton,该函数接下来会检查 ConnorAtherton1、ConnorAtherton2,直到找到唯一的用户名。

这里是函数(我添加了一些echo语句用于调试)

    function createUserName($username, $counter){

        global $fname, $lname;

        echo "\t\t\tUsername at Start - " . $username . "\n";

        // connect to database
        require($_SERVER['DOCUMENT_ROOT'] . "/inc/db.connect.php");

        $stmt = $conn->prepare('SELECT * FROM users WHERE username = ?');
        $stmt->bind_param('s', $username); 
        $stmt->execute();
        $stmt->store_result();

        echo "\t\t\tUsername before loop - " . $username . "\n";

            if( $stmt->num_rows > 0){

                //construct original name and try again
                $username = ucfirst($fname) . ucfirst($lname) . $counter;
                $counter++;
                createUserName($username, $counter);

            }

            echo "\t\t\tUsername after loop - " . $username . "\n\n";

            return $username;
    }

这是它返回到控制台的内容

    Username at Start - ConnorAtherton
    Username before loop - ConnorAtherton
    Username at Start - ConnorAtherton1
    Username before loop - ConnorAtherton1
    Username at Start - ConnorAtherton2
    Username before loop - ConnorAtherton2
    Username after loop - ConnorAtherton2

    Username after loop - ConnorAtherton1

它在循环(ConnorAtherton2)开始后返回正确的值,但我不知道为什么循环后会有第二个值。

它返回 ConnorAtherton1,我需要它返回 ConnorAtherton2。

非常感谢任何帮助。

【问题讨论】:

  • 也许不是您正在寻找的答案,但我会考虑将您的 sql 更改为使用 WHERE username LIKE "ConnorAtherton%",然后将最后一位数字作为子串并添加 1 :)

标签: php function recursion return


【解决方案1】:

代码按预期执行。您所看到的只是从递归调用中展开的堆栈。

您应该修改函数以在递归调用后退出,方法是返回递归调用的结果

     //...
    $counter++;
    return createUserName($username, $counter);
 }
 //... Rest of fn omitted

【讨论】:

  • 太棒了。我很高兴能帮上忙!在相关的说明中,正如其他人指出的那样,您可以在不使用递归的情况下实现相同的目标,但理解递归函数总是可以派上用场;)
【解决方案2】:

你可以在不递归的情况下更容易地实现你想要的。基本逻辑如下所示:

$counter = '';
do {
    $username = ucfirst($fname) . ucfirst($lname) . ($counter++);
} while(!doesNameExist($username));

您只需要实现doesNameExist() 方法。如果名称已经存在,则在那里进行数据库查询并返回 true。

($counter++) 部分将在第一次迭代时附加一个空字符串(++ 后缀会增加变量在评估值之后)。

【讨论】:

  • 嘿迈克尔,我同意你的观点,它可以在没有递归的情况下完成,你的解决方案效果很好。我创建了这个编程场景,以便更好地理解递归的工作原理:)
  • 我明白了。但请记住,如果可能,您应该避免递归调用 - 它们通常比简单循环要昂贵得多。
  • @Michael - 作为一个笼统的声明,我不能同意你的看法。这真的取决于语言和任务。在这种情况下,是的,这有点过头了,但在其他情况下,递归真的很棒!
  • @Miky:你是对的。这取决于它是线性还是迭代递归过程。所以我应该改写我的说法:在 PHP 中,如果有一个更简单的基于循环的解决方案(这里就是这种情况),我会避免它。但话又说回来,什么是“更简单”;)
猜你喜欢
  • 2018-12-05
  • 2012-03-11
  • 2016-01-22
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-21
  • 2017-04-02
相关资源
最近更新 更多