php exec() function and different hosts

心不动则不痛 提交于 2019-12-01 22:36:15
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":

  1. 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).
  2. 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 &");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!