How can I run a PHP script in the background after a form is submitted?

On Linux/Unix servers, you can execute a job in the background by using proc_open:

$descriptorspec = array(
   array('pipe', 'r'),               // stdin
   array('file', 'myfile.txt', 'a'), // stdout
   array('pipe', 'w'),               // stderr
);

$proc = proc_open('php email_script.php &', $descriptorspec, $pipes);

The & being the important bit here. The script will continue even if the original script has ended.


Doing some experimentation with exec and shell_exec I have uncovered a solution that worked perfectly! I choose to use shell_exec so I can log every notification process that happens (or doesn't). (shell_exec returns as a string and this was easier than using exec, assigning the output to a variable and then opening a file to write to.)

I'm using the following line to invoke the email script:

shell_exec("/path/to/php /path/to/send_notifications.php '".$post_id."' 'alert' >> /path/to/alert_log/paging.log &");

It is important to notice the & at the end of the command (as pointed out by @netcoder). This UNIX command runs a process in the background.

The extra variables surrounded in single quotes after the path to the script are set as $_SERVER['argv'] variables that I can call within my script.

The email script then outputs to my log file using the >> and will output something like this:

[2011-01-07 11:01:26] Alert Notifications Sent for http://alerts.illinoisstate.edu/2049 (SCRIPT: 38.71 seconds)
[2011-01-07 11:01:34] CRITICAL ERROR: Alert Notifications NOT sent for http://alerts.illinoisstate.edu/2049 (SCRIPT: 23.12 seconds)

PHP exec("php script.php") can do it.

From the Manual:

If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

So if you redirect the output to a log file (what is a good idea anyways), your calling script will not hang and your email script will run in bg.


Of all the answers, none considered the ridiculously easy fastcgi_finish_request function, that when called, flushes all remaining output to the browser and closes the Fastcgi session and the HTTP connection, while letting the script run in the background.

Example:

<?php
header('Content-Type: application/json');
echo json_encode(['ok' => true]);
fastcgi_finish_request(); // The user is now disconnected from the script

// Do stuff with received data

Note: Due to a wontfix quirk in which calling flush() after fastcgi_finish_request will cause it to exit without warning/error.

You may wish to call ignore_user_abort(true) beforehand to supress this behavior, or simply avoid calling flush() after you've intentionally closed the connection :)

$connected = true;

// Stuff...

fastcgi_finish_request();
$connected = false;

// ...
if ($connected) {
    flush();
}

Or

ignore_user_abort(true);
fastcgi_finish_request();
// Accidental flush()es won't do harm (even if they're still technically a bug)
flush();