I was having a difficult time finding a reliable way to run a background PHP process in Windows, when that was called from an active PHP page. In the *nix world it is relatively simple: by using shell_exec() (or the bactick operator) you can redirect the output to another stream or file and the process will run in the background with no blocking. In Windows, however, this doesn’t seem to work well (or at all, depending on what you are calling via shell_exec()). I did find the answer, though, from piecing together info from the PHP documentation for shell_exec() and the COM class.
That, with a little trial and error and I was able to get a PHP page to fire off a command-line PHP process to run an import of several years data into a new reporting schema. Since this import relies on some serious data manipulation it has a tendency to time out for large data sets. So, I set up the command line script to run six months worth of data and before it exits it starts a new background process for the next six months of data. In this way I was able to complete a many-hour process without worrying about timeouts. I did notice that running in the background (actually in an “invisible” command shell) that the process ran slower than when running in the foreground. This was acceptable, however, since the page returns immediately while the processing begins and the application is still usable while the process is running.
Here is how I call it from the page:
if(isset($_SERVER['PWD'])) { // *nix $basepath = dirname(__FILE__).'/'; $php = 'php'; } else { $basepath = dirname(__FILE__).'\\'; // edit to match your installed target environment $php = "C:\\php516\\php.exe"; } ignore_user_abort(true); set_time_limit(0); $arg1 = 'foo'; $arg2 = 'bar'; $runCommand = "$php -q {$basepath}my_background_running.php $arg1 $arg2"; if(isset($_SERVER['PWD'])) { // *nix // *nix: Use the backtick operator or shell_exec() $nullResult = `$runCommand > /dev/null &`; } else { // Windows: use the php COM class // WScript.Shell gives you the command line $WshShell = new COM("WScript.Shell"); $oExec = $WshShell->Run($runCommand, 7, false); }
I do the same from the background script to call itself recursively right before it exits.
I didn’t find the Microsoft documentation for the Windows Script Host Shell until today during lunch. I found the location in the Practical PHP Programming Online Book where he says to use the Google search “wshell object” msdn which will result in the first link pointing at the MSDN documentation. (I have a feeling it moves around quite a bit, since every link I have run across up to now that points directly at the documentation results in a nice 404 error page at Microsoft.)