PHP 在循环中无限休眠

Posted

技术标签:

【中文标题】PHP 在循环中无限休眠【英文标题】:PHP Sleeping Infinite While Loop 【发布时间】:2015-07-22 07:08:06 【问题描述】:

我在这里做错了什么?我错过了while循环在php中的工作方式吗?即使在页面关闭后,我也希望它在服务器的后台继续循环。

重要提示:即使我保持页面打开,它也不起作用。

我觉得我在使用 PHP 时犯了一个明显的语法错误。

        ignore_user_abort(true);
        set_time_limit(0);

        while(1)
            $dbConnection = mysqli_connect($servername, $username, $password, $dbname); 
            $query = "SELECT user_id FROM users WHERE email = '$user_email'";
            $id = mysqli_query($dbConnection, $query);
            $idrow = mysqli_fetch_assoc($id);
            $result = $idrow['user_id'];

            $querydata1 = "SELECT data1 FROM queue WHERE user_id = '$result'";
            $data1 = mysqli_query($dbConnection, $querydata1);
            $data1row = mysqli_fetch_assoc($data1);
            $resultdata1 = $data1row['data1'];

            if($resultdata1 != NULL)
                $querydata2 = "SELECT data2 FROM queue WHERE user_id = '$result'";
                $data2 = mysqli_query($dbConnection, $querydata2);
                $data2row = mysqli_fetch_assoc($data2);
                $resultdata2 = $data2row['data2'];

                include 'PHPMailerAutoload.php';

                $mail = new PHPMailer;

                $mail->isSMTP();
                $mail->Host = 'smtp.mandrillapp.com';
                $mail->SMTPAuth = true;
                $mail->Username = 'username';
                $mail->Password = 'password';
                $mail->SMTPSecure = 'tls';
                $mail->Port = 587;

                $mail->From = 'test@test.com';
                $mail->FromName = 'test';
                $mail->addAddress($user_email);

                $mail->Subject = 'Test';
                $mail->Body = "$resultdata2"; 

                $mail->send();

             else 
                break;
            

            time_sleep_until(microtime(true)+10);
        

大家好,我又回来了!

所以,我想做的代码是:

    接受用户输入 使用用户输入查询数据库 每 60 秒通过电子邮件发送结果。

我的解决方案是将最后两个阶段放在一个 while 循环中,然后让脚本在最后休眠 60 秒。

结果:我收到一封包含有用数据的电子邮件。

【问题讨论】:

什么是White 循环?或者这是一种绕过可能的欺骗的方法? T 与键盘上的 L 相差甚远。 根本不工作,还是跑了一会儿就停了?如果您在共享主机上,则提供商可能有一个脚本来检查长时间运行的脚本并杀死它们 你怎么知道它不起作用? 安全模式开启了吗? “警告当PHP在安全模式下运行时,此功能无效。除了关闭安全模式或更改php.ini中的时间限制外,没有其他解决方法。” php.net/manual/en/function.set-time-limit.php 您想每 10 秒发送一封电子邮件吗?嗯... 【参考方案1】:

大多数服务器都有执行 php 脚本的时间限制。在大多数情况下,脚本只会在超时之前运行 30 秒。如果您有权访问服务器配置,则可以将其更改为无限。

Set_time_limit(0) 有时无法工作,具体取决于服务器配置。不久前,我尝试了同样的事情,但什么也没做,但是更改服务器中的设置对我来说是这样做的。

编辑

由于抱怨更改服务器上的默认设置可能会产生安全风险,因此您可以做一些不同的事情。查看您想要查询数据的 cmets,然后通过电子邮件发送提及的数据。

您可以通过创建一个遵循您的逻辑的独立 php 脚本(不是 while 循环)来非常轻松地做到这一点。使用 Jquery,您可以在加载网页时根据需要多次调用此脚本。

要让这个脚本在没有用户交互的情况下在后台运行,你需要创建一个定时任务来每隔一段时间调用这个脚本(你可以定义时间间隔)。

【讨论】:

您确实在问题中看到了set_time_limit(0); @arkascha 有时该功能不起作用,具体取决于服务器配置。前段时间我尝试了同样的事情,但什么也没做,但是更改服务器中的设置对我来说是这样做的。 那么你应该在你的答案中写下它。特别是因为您提到使用管理权限更改某些内容。通常在 php 配置中更改此设置将是您创建的一个巨大的安全问题。所以一个非常糟糕的建议。如果您有管理权限,那么您应该建议如何更改配置以使该命令生效。【参考方案2】:

问题在于您使用了break。当您的队列中没有数据时,您会发出中断。这将关闭您的循环,从而结束您的脚本的执行。

continue 在这里继续循环的下一次迭代是合乎逻辑的,但这也会跳过循环底部的睡眠。因此,我认为循环结束时不需要 else 块。如果数据为 NULL,则让它进入睡眠部分并照常继续循环。


附:为什么不只做一个查询:

$querydata = "SELECT data1,data2 FROM queue WHERE user_id = '$result'";

为了获得两个不同的列而使用相同的参数背靠背地执行两个查询似乎是多余的。

【讨论】:

让我们看看 OP 怎么说。希望他们首先发布完整的代码。 弗雷德,来吧,下班。我只是在寻求一点帮助。你太不受欢迎了。 @Devon,我把 else 块拿走了,还是不行,奇怪。 @gregjw,它会发送第一封电子邮件吗?执行是否会在约 10 秒或更长时间后停止? @gregjw Fred 是对的。我可能会超出其他人在 *** 上的期望。至于你的脚本,添加一些调试参数,echo 来跟踪循环运行了多少次,查看最后的输出以了解循环何时退出,确保你有 error_reporting(E_ALL) 和 display_errors。

以上是关于PHP 在循环中无限休眠的主要内容,如果未能解决你的问题,请参考以下文章

哪种方式更方便在无限循环中执行异步函数,每次执行之间都休眠(Node.js / Vanilla JS)

PHP二叉树递归遍历无限循环问题

PHP在用户断开连接时中止无限循环

休眠中ManyToMany关系的无限递归

两个通信类上的PHP无限循环

PHP无限循环取MySQL中的数据。