PHP CGI在命令行exec调用中替换被调用文件的名称,导致无限循环


PHP CGI replaces name of called file in command line exec calls, causing infinite loop

我正在将一个应用程序转移到一个新服务器。应用程序使用命令行调用,新服务器以CGI/FastCGI的形式运行PHP。

问题:在命令行执行的脚本不是exec命令中提到的文件,而是调用文件本身。

应用程序使用exec()在命令行上运行脚本。calling_script.php的整个代码(从实际应用程序中缩小以演示问题)是:

<?
echo __FILE__;
$test = 1;
shell_exec("/usr/bin/php /path/called_script.php ".$test." >> /path/out.log 2>&1 &");

对于called_script.php,它只是:

<?
echo __FILE__;
var_dump($argv[1]);

实际情况是:calling_script.php被调用,而不是called_script.php-参数也会丢失-calling_scriptphp在一个无限循环中被调用,因为对它的每次调用都会导致另一个exec调用再次在它上执行。我尝试了passthrough和shell_exec而不是exec,得到了相同的结果。

我在一个论坛上找到了这样的解释:http://www.mombu.com/php/php-5-forum/t-24759-exec-or-system-et-all-cause-an-infinite-loop-of-starting-requested-program-8469354.html(通过exec()导致启动请求程序的无限循环)

引用:"您正在运行PHP的CGI版本,它会获取脚本名称现在从环境中,而不是从命令行中"更安全"。

有(或应该有)一个ini设置来控制这一点,但是可能希望通过脚本运行PHP的CLI版本相反"

我试图获得PHP的CLI版本,但新服务器由一个提供商管理,没有CLI版本。还有其他解决方案吗?

最终,我想要实现的是php的异步执行——有没有关于在没有CLI版本的php的情况下如何实现这一点的建议?使用CURL、PEAR还是fsockopen?队列或任务队列服务器(如gearman或beanstalkd),如果是,是哪一个?我们衷心欢迎我能够迅速实施的任何解决方案。

为此,您确实应该使用PHP的CLI版本。您可以通过取消设置CGI规范中列出的每个环境变量来偷偷浏览CGI内容。

http://en.wikipedia.org/wiki/Common_Gateway_Interface

<?php
$cmd = array();
// Explicitly clear CGI variables from the environment.  This relies on "E" being
// set in your http://www.php.net/manual/en/ini.core.php#ini.variables-order
foreach ($_ENV as $k => $v) {
  if (preg_match(
      '/^(HTTP_|REQUEST_|SERVER_|PATH_|DOCUMENT_ROOT|GATEWAY_INTERFACE)/', $k)) {
    $cmd[] = "$k=''";
  }
}
// Generates a command like: "GATEWAY_INTERFACE='' /usr/bin/php myscript.php"
$prefix = implode($cmd, ' ');
shell_exec("$prefix /usr/bin/php myscript.php");

我也遇到了同样的问题。解决方案很简单。只需添加exit();在系统()调用之后。

适用于我phpfcgi 5.6 Centos,cpanel easy apache 4

系统("/usr/bin/php/path/called_script.php".$test.">>/path/out.log 2>&1&");exit();