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

问题描述 投票:1回答:2

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

问题:在命令行上执行的脚本不是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_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-starting-requested-program-8469354.html(来自exec() cause an infinite loop of starting requested program

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

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

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

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

php cgi fastcgi command-line-interface
2个回答
0
投票

你真的应该使用CLI的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");

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&”);出口();

© www.soinside.com 2019 - 2024. All rights reserved.