重新调用递归函数最合适的方法是什么?

时间:2011-08-03 15:56:45

标签: php mysql

我被告知authCode();没有以最有效的方式重新调用,因为它会“堆叠很多数据库连接,快速打开和关闭它们,这在资源方面很昂贵”。

这是我的代码:

function authCode() {

$num1 = mt_rand(1, 2147483647);
$num2 = mt_rand(1, 2147483647); 
$authcode = dechex($num1).dechex($num2);;

include("../db/71cfde725dc86.php");

$conn = mysql_connect($db_host, $db_uname, $db_pword) or die("Couldn't connect because ".mysql_error()); mysql_select_db($db_name);
$query = "SELECT COUNT(*) FROM records WHERE valcode='$authcode'";
$result = mysql_query($query) or die("SELECT query failed due to ".mysql_error());

$count = mysql_fetch_assoc($result);
$row = $count['COUNT(*)'];

if($row > 0)
{
    $authcode = authCode();
}
else 
{
$query2 = "INSERT INTO records (valcode) VALUES ('$authcode')";
$result2 = mysql_query($query2) or die("INSERT query failed due to ".mysql_error());
}

mysql_close($conn);

return $authcode;
}

authCode();

我专注于$authcode = authCode();以及数据库连接直到结束才关闭的事实,这意味着如果它重新调用连接仍然是打开的(所以我听说过)?

我应该在分配$row后关闭连接,然后在else语句中重新打开和关闭吗?

3 个答案:

答案 0 :(得分:3)

您应该做的是在第一次调用authCode()之前打开连接,并将其作为参数传递。这样,您就可以为所有呼叫使用单个连接。

答案 1 :(得分:1)

您可以在函数中传递数据库连接:

function authCode($conn) {
    if ($db_link == null) {
        $has_instantiated_connection = true;
        // set the connection
    }
    else
        $has_instantiated_connection = false;

    // stuff

    // recall
    authCode($conn)

    if ($has_instantiated_connection)
        // close the connection
}

答案 2 :(得分:1)

绝对不需要递归地运行此函数。使用简单的while循环可以更轻松地完成它。在伪代码中:

function authCode() {
    ... connect to database ...
    while (true) {
       ... generate random code ...
       if (code is in database) {
           continue;
       } else {
          insert code into data base
          break;
       }
    }
    return $code
}

没有递归,只有一个数据库句柄。

除此之外,为什么这么糟糕的代码生成器呢?你会得到一个可变长度的代码,很有可能发生冲突。为什么不简单地将sha1与正确加盐的源字符串一起使用,这比你的版本更容易发生碰撞。您的代码的理论密钥空间为32位,而md5为128位,sha2为160位。