Monday, August 09, 2010

Calling the php interpreter within web script

Recently, part of a development required me to execute shell script as part of a web request. The design was to kick start a long running php process (via shell script), which would run beyond the length of a standard web request. To do this, I used forking shell script and popen... (if using shared hosting, shell execution methods are generally disabled - check php.ini's disable_functions config value to verify).

Within my dev environment (Windows) I was able to execute the following with no issues:

popen("start /b php my_script.php my_args", "w");
Note: 'start /b' forks a windows process - making it run in the background



When executing its equivalent in a Linux environment
popen("php my_script.php my_args &", "w");

In Linux, the server was thrown into a state of confusion, perpetually executing, then aborting the requested shell script command (infinitely starting and exiting the requested php script in the popen command). Obviously explicitly calling the php interpreter from within an executing php process is a particularly nasty thing to do.

I'm assuming this sort of thing doesn't happen in windows as shell script executes in its own command window (which when using proc_open with get_proc_status makes getting a correct PID value problematic). Anyone with futher insight - feel free to leave comments.

To get around this issue, I ensured that in the linux environment, the shebang path to the interpreter appeared on the first line of the executing script, and it was chmod'ed to allow direct cli execution... ie

my_script.php:
#!/usr/local/bin/php

//
// my code
//
?>

CHMOD command used:
chmod 755 my_script.php

Then finally the linux popen command:
popen("./my_script.php my_args &", "w");

The default working directory of popen, and all other shell script execution methods is always web root (so my_script.php sat in the web root dir).

The same issue occurs with all other shell script execution methods:
system, exec, proc_open, passthru, back ticks (`) etc.