2

我正在尝试使用以下代码生成 1500 身份验证代码:

    <?php
include "../include/top.php";

set_time_limit(0);
ini_set("memory_limit", "-1");

$end=0;
while ($end<1500)
{
//generate an authentication code
$string="ABCDEFGHJKLMNPQRSTUVWXYZ123456789";
$string= substr(str_shuffle($string),5,8) ;

//check whether generated code already exist
$query = "select count(*) from auth where code = '$string' ";
$stmt = prepare ($query);
execute($stmt);
$bind = mysqli_stmt_bind_result($stmt, $count);
check_bind_result($bind);
mysqli_stmt_fetch($stmt);
mysqli_stmt_free_result($stmt);

//If generated code does not already exist, insert it to Database table
if ($count == 0)
    {
    echo $string."<br>";
    $query = "insert into auth (Code) values ('$string')";
    $stmt = prepare ($query);
    execute($stmt);
    $end++;
    }
}
?>

它在数据库中生成并插入了 1024 个代码,并在 15 秒内在浏览器中打印了 667 个代码,并且浏览器继续加载而不插入/打印更多代码,直到半小时后我关闭浏览器窗口。之后,当从 WAMP 在浏览器中打开任何网页时,它显示为浏览器正在加载并且不显示内容。也就是说,在打开任何网页之前,我需要在运行此脚本后重新启动 WAMP。我已经试过很多次了。

为什么脚本不生成 1500 个代码并且在达到计数 667/1024 时总是停止?

更新

作为实验,我在 IF 条件中添加了一个 ELSE 子句,并编写了代码以在 ELSE 子句中打印“代码已存在”。并使用同一张表的空(截断)副本运行脚本,然后打印并插入 1024 个代码,然后连续打印“代码已存在”(5 分钟内约有 700 000 多个条目并继续)。再次使用只有 1024 行的表运行脚本时,它甚至不会打印或插入单个代码。相反,它无限地继续打印“代码已经存在”。我观察到的另一件事是,WHILE 循环的第一个 1024 次迭代通过了 IF 条件(如果表为空)。并且所有后续迭代都失败了 IF 条件。

4

3 回答 3

2

我不认为 str_shuffle 中的随机化器可以做到这一点。

如果我在获得 1024 个唯一代码后运行它,然后它只会生成重复项。如果我然后重新启动它,它将生成另外 976 个唯一代码,在数据库中总共提供 2000 个代码。

因此,我假设使用的随机str_shuffle()数发生器需要重置才能生成所需的 1500 个唯一代码。

试试这个小修改,它至少会在 15000 次尝试生成唯一代码失败后停止执行。

基本上我认为你必须想出一个更好的随机化机制。

<?php
include "../include/top.php";

set_time_limit(0);
ini_set("memory_limit", "-1");

$end=0;
$dups=0;
while ($end<1500 && $dups < 15000)
{
    //generate an authentication code
    $string="ABCDEFGHJKLMNPQRSTUVWXYZ123456789";
    $string= substr(str_shuffle($string),5,8) ;

    //check whether generated code already exist
    $query = "select count(*) from auth where code = '$string' ";
    $stmt = prepare ($query);
    execute($stmt);
    $bind = mysqli_stmt_bind_result($stmt, $count);
    check_bind_result($bind);
    mysqli_stmt_fetch($stmt);
    mysqli_stmt_free_result($stmt);

    //If generated code does not already exist, insert it to Database table
    if ($count == 0) {
        echo $string."<br>";
        $query = "insert into auth (Code) values ('$string')";
        $stmt = prepare ($query);
        execute($stmt);
        $end++;
    } else {
        $dups++
        echo "DUPLICATE for $string, Dup Count = $dups<br>";
    }
}
?>

为什么你需要重新启动 = 你设置了 php 超时,所以它永远不会超时。

于 2014-04-04T12:23:19.893 回答
1

我没有看到任何特定的编码错误。使用 str_shuffle 创建验证码是很特殊的,因为它可以防止重复的字母,使可能的值范围更小。所以它可能只是在重复这些模式。

试试这样的事情,这样你就可以洗牌了:

$origstring= str_shuffle("ABCDEFGHJKLMNPQRSTUVWXYZ123456789");

while ($end<1500 && $dups < 15000)
{
   $origstring = str_shuffle( $origstring);
   $string = substr( $newstring, 5, 8);

或者,使用类似这样的东西来生成字符串,以便您可以有重复项,从而创建更大范围的可能值:

   $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
   for ($i = 0; $i < 8; $i++)
   {
      $code .= $characters[mt_rand(0, 35)];
   }
于 2014-04-04T15:29:36.450 回答
0

您必须微调php.ini配置文件中的一些变量,找到那些:

; Maximum execution time of each script, in seconds
; http://php.net/max-execution-time
; Note: This directive is hardcoded to 0 for the CLI SAPI
max_execution_time = 600    

而且,不是强制性的,您也可以更改它们:

suhosin.post.max_vars = 5000   
suhosin.request.max_vars = 5000

修改后,重新启动您的 Web 服务器。

于 2014-04-03T10:33:17.790 回答