【问题标题】:problems with infinite loop无限循环的问题
【发布时间】:2023-03-28 21:25:01
【问题描述】:
function addAds($n) {
 for ($i=0;$i<=$n;$i++) {
  while($row=mysql_fetch_array(mysql_query("SELECT * FROM users"))) {
   $aut[]=$row['name'];
  }
  $author=$aut[rand(0,mysql_num_rows(mysql_query("SELECT * FROM users")))];
  $name="pavadinimas".rand(0,3600);
  $rnd=rand(0,1);
  if($rnd==0) {
   $type="siulo";
  } else {
   $type="iesko";
  }
  $text="tekstas".md5("tekstas".rand(0,8000));
  $time=time()-rand(3600,86400);
  $catid=rand(1,9);
  switch ($catid) {
   case 1:
    $subid=rand(1,8);
    break;
   case 2:
    $subid=rand(9,16);
    break;
   case 3:
    $subid=rand(17,24);
    break;
   case 4:
    $subid=rand(25,32);
    break;
   case 5:
    $subid=rand(33,41);
    break;
   case 6:
    $subid=rand(42,49);
    break;
   case 7:
    $subid=rand(50,56);
    break;
   case 8:
    $subid=rand(57,64);
    break;
   case 9:
    $subid=rand(65,70);
    break;
  }
  mysql_query("INSERT INTO advert(author,name,type,text,time,catid,subid) VALUES('$author','$name','$type','$text','$time','$catid','$subid')") or die(mysql_error());
 }
 echo "$n adverts successfully added.";
}

这个函数的问题是它永远不会加载。正如我所注意到的,我的 while 循环导致了它。如果我评论它,一切都很好。它必须从我的数据库中获取随机用户并将其设置为变量 $author。

【问题讨论】:

  • 你有一个 SQL 注入漏洞
  • @SLacks,不,他们没有。所有值都从数据库中提取或在函数中生成。唯一看起来有问题的可能是 users 表,但这仍然是一个延伸。
  • @Brendan Long - 仅仅因为值来自数据库并不意味着它是干净的。在问题的范围内,如何阻止users 中的一行出现name','','','','','','');insert into table sql_injection_attacks values (TIME());
  • 它是否可能并不重要,每个人都应该一直安全地做数据库工作,而不是花一秒钟的时间思考“等等,会不会这很危险? "
  • @Richard JP Le Guen - 但现在你只是在假设。有多少人在他们的用户名中允许使用这样的标点符号?这当然是可能的,但仅凭这个函数你不能只说“存在 SQL 注入漏洞”。

标签: php infinite-loop


【解决方案1】:

问题是查询在循环中,所以它每次都会运行(所以你每次都从头开始)。只需将 mysql_query() 部分移到 while 循环之前的右侧并将其存储在变量中即可:

$query = mysql_query("SELECT * FROM users");
while($row=mysql_fetch_array($query))

【讨论】:

    【解决方案2】:

    你可以用一行替换这个巨型开关:

    $subid = rand(($catid * 8) - 7, min($catid * 8, 70));
    

    【讨论】:

    • @Gumbo:考虑到这个随机数,我认为这是一个很好的近似值;-) 但是如果他们不想要 aproxx,他们可以添加到这 3 行并获得 100% 的反射。 4 行优于 29。
    • 好吧,既然它使用rand,你也可以写$subid=4;。 ;-)
    【解决方案3】:

    每次迭代都会执行和评估while 循环的条件。所以每次迭代都会调用mysql_query,并返回true。

    只需执行一次数据库查询并缓存结果:

    function addAds($n) {
        $result = mysql_query("SELECT * FROM users");
        $aut = array();
        while ($row = mysql_fetch_array($result)) {
            $aut[]=$row['name'];
        }
        $rowCount = count($aut);
        for ($i=0; $i<=$n; $i++) {
            $author=$aut[rand(0,$rowCount)];
            // …
            mysql_query("INSERT INTO advert(author,name,type,text,time,catid,subid) VALUES('$author','$name','$type','$text','$time','$catid','$subid')") or die(mysql_error());
        }
        echo "$n adverts successfully added.";
    }
    

    【讨论】:

      【解决方案4】:

      我还认为问题在于您的功能太大而无法理解(很快)。您应该将它们变小并使用 phpunit 之类的单元测试框架对其进行测试。

      【讨论】:

        【解决方案5】:

        很多时候我不使用PHP,但我认为分配

        $row=mysql_fetch_array(mysql_query("SELECT * FROM users"))
        

        应该总是返回true,它在每次迭代中一次又一次地执行查询..

        【讨论】:

          【解决方案6】:

          每次运行循环时都会开始一个新查询。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-03
            • 2021-09-02
            • 2020-09-09
            • 2021-09-11
            • 2018-09-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多