I have a script that executes a file in a couple of directories down which looks like this:
exec("php-cli $file_path > /dev/null 2>/dev/null &"); //php command-line
This works on most hosts but some hosts don't like it and it doesn't run, without generating any error.
For the hosts that this fails on, i use
exec("php $file_path > /dev/null 2>/dev/null &"); //notice the -cli is gone
Which works fine.
$file_path is the full path to the file being executed /home/blah/path/blah.php
How can i make this uniform so it works on all servers (unix at least)
**EDIT**
Well, I'm doing it this way, it is (most likely) not the correct way but it works.
Instead of just using php-cli or php, i use both so if one fails, the other goes through. Either the php is running as cgi or cli and one of these will catch, and since there is no output, there would be no error either.
exec("php-cli $file_path > /dev/null 2>/dev/null &");
exec("php $file_path > /dev/null 2>/dev/null &");
Unless you know a better solution please let me know. Thanks for all your help.
function php_exec($file_path) {
if (!($binary = which(array('php', 'php5', 'php-cli', 'php-cgi'))))
return false;
return exec("$binary $file_path > /dev/null 2>/dev/null &");
}
function which($binaries) {
if (!($path = getenv('PATH')) && !($path = getenv('Path')))
return false;
$arr = preg_split('/[:;]/', $path);
foreach ($arr as $p) {
foreach ($binaries as $b) {
if (file_exists("$p/$b"))
return "$p/$b";
}
}
return false;
}
var_dump(php_exec('test.php'));
Explanation:
On most systems the PHP binary is called php, php5, php-cli or php-cgi. which() function checks the standard path (both *nix and windows have environment variable called PATH/Path) for each of those names and if it find a file with such name, it will return it.
The PATH variable's format is: /bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
for *nix (bash), and C:\Windows\System32\;C:\Windows\;
for windows, so that's why I use preg_split('/[:;]/')
This solution is better than yours, because php_exec() will return false
if it can't find a valid php binary. In your solution there's no way to know if the script execution failed.
It depends on how the PHP-CLI binary is compiled. On most systems the executable is named just 'php' and I guess that the hosts that have 'php-cli' have it compiled by hand, while most of the others have it installed via the OS package manager.
You have two options to work around that and make it "universal":
- On each of the servers, add an alias for one of them where needed, or make a symlink to the PHP executable somewhere (e.g. in your home directory).
- Prior to executing, check which one of them exists (usually, it should be located in /usr/bin/) and set it to a variable.
Simple question perhaps, but does php-cli
exist on all the hosts? I assume the reason its failing silently is because you're telling it to be redirecting everything away.
exec("php $file_path > /some/writable/path/output.log 2>/some/writable/path/error.log &");