3

我有一个脚本,它在几个目录中执行一个文件,如下所示:

exec("php-cli $file_path > /dev/null 2>/dev/null &"); //php command-line

这适用于大多数主机,但有些主机不喜欢它并且它不会运行,不会产生任何错误。

对于失败的主机,我使用

exec("php $file_path > /dev/null 2>/dev/null &"); //notice the -cli is gone

哪个工作正常。

$file_path 是正在执行的文件的完整路径 /home/blah/path/blah.php

我怎样才能使这个统一,以便它适用于所有服务器(至少是 unix)

**编辑* *

好吧,我正在这样做,它(很可能)不是正确的方法,但它确实有效。

我不只是使用 php-cli 或 php,而是同时使用两者,所以如果一个失败,另一个会通过。php 作为 cgi 或 cli 运行,其中之一将捕获,并且由于没有输出,因此也不会出现错误。

exec("php-cli $file_path > /dev/null 2>/dev/null &");
exec("php $file_path > /dev/null 2>/dev/null &");

除非您知道更好的解决方案,否则请告诉我。感谢你的帮助。

4

3 回答 3

5
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'));

说明:在大多数系统上,PHP 二进制文件称为 php、php5、php-cli 或 php-cgi。which() 函数检查每个名称的标准路径(*nix 和 windows 都有名为 PATH/Path 的环境变量),如果找到具有该名称的文件,它将返回它。

PATH 变量的格式是:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin对于 *nix (bash),C:\Windows\System32\;C:\Windows\;对于 windows,这就是我使用 preg_split('/[:;]/') 的原因

这个解决方案比你的解决方案更好,因为false如果 php_exec() 找不到有效的 php 二进制文件,它将返回。在您的解决方案中,无法知道脚本执行是否失败。

于 2012-05-03T14:34:58.967 回答
1

也许是一个简单的问题,但php-cli所有主机上都存在吗?我认为它默默失败的原因是因为你告诉它要重定向所有东西。

exec("php $file_path > /some/writable/path/output.log 2>/some/writable/path/error.log &");
于 2012-05-03T13:03:55.857 回答
1

这取决于 PHP-CLI 二进制文件的编译方式。在大多数系统上,可执行文件仅命名为“php”,我猜有“php-cli”的主机是手动编译的,而其他大多数系统都是通过操作系统包管理器安装的。

您有两种选择可以解决这个问题并使其“通用”:

  1. 在每台服务器上,在需要的地方为其中一个添加别名,或者在某处(例如,在您的主目录中)创建指向 PHP 可执行文件的符号链接。
  2. 在执行之前,检查其中哪一个存在(通常应该位于 /usr/bin/ 中)并将其设置为变量。
于 2012-05-03T13:14:35.473 回答