【问题标题】:PHP: Execute a function inside a while loop every 10 secondsPHP:每10秒在while循环内执行一个函数
【发布时间】: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)进行简单的基于间隔的轮询
  • @Mr.Jo 请在下面查看我的答案,我认为它解决了(几乎,如果不是全部)您在此处提到的问题。

标签: php loops while-loop


【解决方案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 中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 2017-03-02
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      相关资源
      最近更新 更多