我不懂PHP sleep()行为

时间:2013-05-31 18:54:24

标签: php sleep

我有这样的表格:

<form method="post" action="secret.php">
    <label for="pw">Password: </label><input type="password" name="pw" id="pw" />
</form>

这是secret.php:

<?php 
if(isset($_POST["pw"])) {
    if($_POST["pw"] == "hello") {
        echo("<strong>Good pw.</strong><br />");
    } else {
        echo("<strong>Bad pw.</strong><br />");
        echo("<a href=\"form.php\">Back</a>");
        sleep(5);
    }
} else {
    header("Location: /tut/first/form.php");
}
?>

如果密码错误,它会在显示Bad pw之前休眠。当我提交表单时,它会在表单页面上<5>秒,然后更改页面并显示Bad pw。为什么呢?

3 个答案:

答案 0 :(得分:4)

发生的事情是您正在使PHP脚本进入休眠状态。脚本必须在将结果发送回客户端(浏览器)之前完成。*因此,在脚本响应客户端不是一个好密码之前,脚本需要花费5秒钟。

既然你不想在这里避免蛮力的情况,我会建议这样的事情:

<?php 
if(isset($_POST["pw"])) {
    if($_POST["pw"] == "hello") {
        echo("<strong>Good pw.</strong><br />");
    } else {
        echo("<strong>Bad pw.</strong><br />");
        echo("<script type=\"text/javascript\">");
            echo ("setTimeout(function() {");
                echo ("window.location = form.php;"); //might need a more complete URL here
            echo ("}, 5)"); //sleep for 5 seconds before redirecting
        echo("</script>");
        sleep(5);
    }
} else {
    header("Location: /tut/first/form.php");
}
?>

* 输出实际上是在PHP脚本中写回来的,但是在缓冲的情况下,除了标题和非常大的页面之外,你不会发现这种情况有很大的不同。

答案 1 :(得分:0)

你需要研究输出缓冲,虽然从我看来,逻辑是有缺陷的。

This可能有所帮助

答案 2 :(得分:0)

如果您想立即向浏览器回显某些内容,请在要将输出缓冲区刷新到浏览器时尝试flush()。此外,您可能需要禁用可能干扰输出缓冲的压缩(如gzip)。

然而,尽管如此,你说这完全错了。用户必须做的就是打开另一个选项卡/刷新,服务器将再次验证登录信息,因此执行sleep()不会产生您认为的效果。

我实际上设计了类似于此的东西,这就是我所做的:

创建一个名为failed_logins的数据库表,另一个名为login_bans,两者都基于IP地址。每次用户提供不正确的信息时,请在failed_logins表中添加一个条目。您想要做的是对其进行分层,以便在第一次登录后,用户被禁止5秒,在第二次登录后,它会在一定时间内(例如说2小时)达到15秒和3或更长时间被禁止禁止45秒。这一切都是在服务器端完成的,因此用户无法绕过禁令。因此,每次访问页面时都必须检查其IP,以查看其IP是否已被禁止。

然后在客户端显示一个倒数计时器,其中包含禁令中剩余的秒数并禁用提交按钮。