Run a PHP Script in the Background After a Form Has Been Submitted
The relationship between PHP and the browser can cause problems. Suppose a user submits a form that executes a PHP script, which:
- Processes a credit card.
- Displays a confirmation to the user.
- Adds the user to a database.
- Sets up a user account.
- Sends the user a welcome email.
If the script takes 1 minute to execute then the user will have to sit there waiting for a minute before they see the confirmation message. If the user clicks the browser's stop button, that will kill our script before it has completed.
I ran into this issue a while back because I wanted to process a credit card, register a domain name via an API, set up a local hosting account, add the user to a mailing list via an API, send an admin email, and then send a welcome email to the user. This all took about 45 seconds to process. I needed a way to send a response to the browser right after the credit card was approved, but then keep processing PHP code in the background.
Here's the solution I found...
<?php
// put your email address here to see the script in action
$email = 'my@mysite.com';
// don't let user kill the script by hitting the stop button
ignore_user_abort(true);
// don't let the script time out
set_time_limit(0);
// start output buffering
ob_start();
// If you need to return data to the browser, run that code
// here. For example, you can process the credit card and
// then tell the user that their account has been approved.
usleep(1500000); // do some stuff...
$myvar = "The browser gets updated quickly, but the script keeps processing in the background. As proof, you'll get an email about 2 minutes from now, when the script finishes.";
echo $myvar;
// now force PHP to output to the browser...
$size = ob_get_length();
header("Content-Length: $size");
header('Connection: close');
ob_end_flush();
ob_flush();
flush(); // yes, you need to call all 3 flushes!
if (session_id()) session_write_close();
// everything after this will be executed in the background.
// the user can leave the page, hit the stop button, whatever.
usleep(120000000); // do some stuff
mail($email, 'PHP Background Processing', "This took 2 minutes to process, but the browser didn't hang during that time. Pretty cool!");