Mr. Jo
Mr. Jo

Reputation: 5281

PHP: Execute a function inside a while loop every 10 seconds

I've this while loop here:

$payment_timeout = time() + 300;

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

    break;
}

This loop get's called via an AJAX function. The plan is to wait until a customer paid something. To check this, I've build a is_valid() function which does a check against the database to check if the order was paid.

The problem is that in this case my database will crash because of the amount of requests. So I'm looking for a way to execute the check every 10 seconds or so and the other times just do the continue.

Is there a way to do this?

Upvotes: 0

Views: 1944

Answers (3)

Mr. Jo
Mr. Jo

Reputation: 5281

I'm using now a setInterval() function to check:

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

This works great for me and is simple

Upvotes: 0

webketje
webketje

Reputation: 11006

Below is a simple generic implementation of a polling mechanism in Javascript, working with variable endpoint, intervals, durations, and callback.

The assumption is that you remove the while loop from the PHP code, and make sure you send back a valid JSON response. In the callback parameter I've given below the assumption is that PHP sends back json_encode(['paid' => 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);

NB: XHR = XMLHttpRequest; what @Giacomo shows is not long-polling, long-polling is a client-server technique which involves keeping connection requests open.

Upvotes: 1

Giacomo M
Giacomo M

Reputation: 4723

You can do a "long-polling" with javascript.
It is very simple: a javascript function that runs every X seconds (in your case 10) and do a call to the server.

From this post Using setInterval() to do simplistic continuous polling you can do:

// 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();

If you want to stop the calls after 5 minutes, you just have to set a counter variable and check it in the refresh function.
Something like (pseuso code):

IF YOUR_COUNTER < 5 MINUTES THEN
    CALL REFRESH AGAIN

at the end of the refresh function.

Upvotes: 1

Related Questions