PHP:每10秒在while循环内执行一个函数

Posted

技术标签:

【中文标题】PHP:每10秒在while循环内执行一个函数【英文标题】:PHP: Execute a function inside a while loop every 10 seconds 【发布时间】:2019-08-12 23:06:31 【问题描述】:

我这里有这个while循环:

$payment_timeout = time() + 300;

while ( time() < $payment_timeout ) 
    if (is_valid()) 
        continue;
    

    break;

通过 AJAX 函数调用此循环。计划是等到客户付钱。为了检查这一点,我构建了一个is_valid() 函数,它对数据库进行检查以检查订单是否已支付。

问题是在这种情况下我的数据库会因为请求的数量而崩溃。所以我正在寻找一种方法来每隔10 seconds 左右执行一次检查,而其他时间只是继续。

有没有办法做到这一点?

【问题讨论】:

您在寻找sleep() 函数吗?请小心使用。例如,您可以每 10 秒发起一次 AJAX 调用。 反过来呢:使用观察者模式。当数据库更改时,您将更改发送给所有侦听器。 @Mr.Jo 你不需要 websockets 来使用 XHR(通过 javascript)进行简单的基于间隔的轮询 查看此帖***.com/questions/8682622/… @Mr.Jo 请在下面查看我的答案,我认为它解决了(几乎,如果不是全部)您在此处提到的问题。 【参考方案1】:

您可以使用 javascript 进行“长轮询”。 这很简单:每 X 秒运行一次(在您的情况下为 10 秒)并调用服务器的 javascript 函数。

从这个帖子Using setInterval() to do simplistic continuous polling你可以做到:

// This function is called every 10000 milliseconds (10 seconds)
function refresh() 
    // make Ajax call here, inside the callback call:

    // call itself again after 10 seconds
    setTimeout(refresh, 10000);


// if you want to wait 10 seconds for the first call
setTimeout(refresh, 10000);
// or if you want to call immediately the first time
refresh();

如果你想在 5 分钟后停止调用,你只需要设置一个计数器变量并在刷新函数中检查它。 类似(伪代码):

IF YOUR_COUNTER < 5 MINUTES THEN
    CALL REFRESH AGAIN

refresh 函数的末尾。

【讨论】:

【参考方案2】:

下面是 Javascript 中轮询机制的简单通用实现,使用可变端点、间隔、持续时间和回调。

假设您从 php 代码中删除了 while 循环,并确保您返回一个有效的 JSON 响应。在我在下面给出的回调参数中,假设 PHP 发回 json_encode(['paid' =&gt; true])

// interval & duration in seconds
function poll(endpoint, interval, duration, callback) 
  var xhr = new XMLHttpRequest();
  xhr.open('GET', endpoint);
  xhr.onload = function() 
    var message;
    try 
      message = JSON.parse(xhr.response);
     catch(err) 
      // malformed json
    
    if (duration >= 0 && callback(message) !== false) 
      setTimeout(function() 
        poll(interval, duration - interval, callback);
      , interval * 1000);
    
  ;
  xhr.send();


// usage
var endpoint = '/your-validity-check.php',
   interval = 10, // every 10 seconds
   duration = 5 * 60, // for 5 minutes
   callback = function(response) 
    var date = new Date();
    console.log(response.paid);

    // return false to abort the polling when we know the purchase is paid
    if (response.paid) 
      window.alert('Thank you for your purchase!');
      return false;
              
   ;

poll(endpoint, interval, duration, callback);

注意:XHR = XMLHttpRequest; @Giacomo 显示的不是长轮询,long-polling 是一种客户端-服务器技术,涉及保持连接请求打开。

【讨论】:

【参考方案3】:

我现在使用 setInterval() 函数来检查:

let interval = setInterval( function () 
    //If max time of 5 minutes exceeded (5 * 60000) I leave the interval
    if ( new Date().getTime() - startTime > 300000 ) 
        clearInterval( interval );
    
    //Here I'm doing my AJAX request to check the payment status
, 5000 ); //<- Execute every 5 seconds

这对我来说很好用,而且很简单

【讨论】:

把它不在 PHP 中

以上是关于PHP:每10秒在while循环内执行一个函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用游戏循环每五秒在屏幕上出现和消失一个对象

每 3 秒在屏幕上创建和显示游戏对象

每 N 秒在后台线程中重复一个函数

无限while循环内的Sleep()函数

while 循环

使用 sleep() 函数作为带有 while 循环的计时器不起作用?