1

我正在将应用程序转移到新服务器。应用程序使用命令行调用,新服务器将 PHP 作为 CGI/FastCGI 运行。

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

该应用程序使用 exec() 在命令行上运行脚本。call_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,而不是calling_script.php - 并且参数也丢失了-calling_script.php 在无限循环中被调用,因为每次调用它都会导致另一个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-启动请求程序 8469354.html (通过exec() 导致启动请求程序的无限循环

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

有(或应该有)一个 ini 设置来控制它,但是,您可能希望从您的脚本中运行 PHP 的 CLI 版本。”

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

最终,我想要实现的是 php 的异步执行——关于我如何在没有 CLI 版本的 PHP 的情况下实现这一点的任何建议?使用 CURL、PEAR 或 fsockopen?队列或任务队列服务器(例如 gearman 或 beanstalkd),如果是,是哪一个?任何我可以快速实施的解决方案都受到热烈欢迎。

4

2 回答 2

0

你真的应该为此使用 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");
于 2013-08-06T03:20:31.300 回答
0

好吧,我有同样的问题。解决方案很简单。只需添加 exit(); 在 system() 调用之后。

为我工作 phpfcgi 5.6 Centos,cpanel easy apache 4

system("/usr/bin/php /path/called_script.php ".$test." >> /path/out.log 2>&1 &"); 出口();

于 2017-12-21T17:03:47.330 回答