无法在 PHP 文件中包含/执行 CGI 文件

Posted

技术标签:

【中文标题】无法在 PHP 文件中包含/执行 CGI 文件【英文标题】:Can't include/execute a CGI file inside a PHP file 【发布时间】:2012-05-08 23:35:39 【问题描述】:

使用 SSI,我可以简单地将其包含在我的 html 文件中,然后 CGI 脚本的输出将显示在页面上:

<!--#include virtual="script.cgi"-->

现在我正在尝试做同样的事情,但它不是 HTML 文件,而是在 php 文件中。我整天都在研究这个问题,每个解决方案都给我带来了以下问题。我将列出它们,从我认为应该工作以及晦涩难懂的开始......


1) &lt;?php include("script.cgi"); ?&gt;

结果:没有执行。这只是打印出 CGI 文件的全部内容,就好像它只是一个文本文件一样。


2)&lt;?php virtual("script.cgi"); ?&gt;

结果: Fatal error: Call to undefined function virtual() in test.php on line #.

这让我很困扰,因为我阅读的所有内容都表明这是正确的做法。我不是 PHP 专家,但 virtual 怎么可能是“未定义函数”? listed in the official PHP docs 对 PHP 版本 5 有效。


3)&lt;?php exec("script.cgi"); ?&gt;

结果:空白。什么都没有。


4)

<?php
    $fd = fopen("script.cgi", "r");
    fpassthru($fd);
?>

结果:没有执行。这只是打印出 CGI 文件的全部内容,就好像它只是一个文本文件一样。


5)&lt;?php echo system("script.cgi"); ?&gt;

结果:好坏参半。它会执行,但 CGI 脚本的“结果”会打印两次,并且前面是“Content-type: text/html”。这个我不明白。

Content-type: text/html resultresult

并通过删除 echo...

&lt;?php system("script.cgi"); ?&gt;,结果...

Content-type: text/html result


6)&lt;?php print("/usr/bin/perl script.cgi"); ?&gt;

结果:没有执行。它只是打印出 print 语句 (/usr/bin/perl script.cgi) 之后包含的内容。 (我并不感到惊讶,但论坛中有人声称这对他们有用。)


那么我需要做什么才能执行并包含 CGI 文件的结果?这似乎应该很容易,但我不知道还能尝试什么。

我在一个 Apache/Linux 服务器 (cPanel) 上,可以编辑 htaccess 文件。它运行 PHP 5.2.17 版。

是的,当我在浏览器中提取 CGI 文件时,它会执行并显示结果,因此我们知道服务器已配置为执行 CGI 文件。

【问题讨论】:

“这个函数 (virtual) 仅在 PHP 作为 Apache 模块安装时才支持。” - PHP 是作为 Apache 模块安装的吗? @deceze,老实说,我不知道,PHP 是预装在帐户上的。有没有办法告诉我? @ColeJohnson,这个特殊的函数可以很容易地转换为 PHP,但我真的很想知道如何在我无法解决的任何情况下解决这个问题。 @deceze 试试 php_info() 看看它是作为一个模块安装还是仅仅被调用 【参考方案1】:

如果 PHP 作为 Apache 模块运行,则 CGI 变量在内部传递。在调用希望在环境中找到它们的 CGI 脚本之前,应该将它们复制到那里。

然后,CGI 脚本可能会在内容之前写入 HTTP 响应标头。似乎没有办法阻止 PHP 显示标题。所以脚本必须适当地处理脚本输出。

例如:

<?php
    foreach($_SERVER as $key => $value)
        putenv("$key=$value");
    $rtc = 0;
    $out = array();
    $mycgi = "/full/path/to/my/script.cgi";
    exec($mycgi, $out, $rtc);
    $in_header = true;
    foreach($out as $value)
    
        if ($in_header)
        
            if (strlen($value) == 0)
                $in_header = false;
            else
                header($value);
        
        else
        
            echo "$value\n";
        
    
    if ($rtc)
        error_log("$mycgi rtc=$rtc", 0);
?>

【讨论】:

【参考方案2】:

试试

passthru("/usr/bin/perl /full/path/script.cgi");

【讨论】:

不好。结果和我的5b一样。 Content-type: text/html result.【参考方案3】:

我已经尝试了所有方法,但似乎没有任何工作正常或根本没有工作。因此,对我来说,唯一的答案是它只是不能不应该做。此外,将 CGI/Perl 与 PHP 混合可能不是最佳实践。

将任何小的 CGI/Perl 脚本简单地重写为 PHP 应该不会太难。任何太大而无法重写的东西,那么在这种情况下,最好在整个网站上坚持使用 Perl。

【讨论】:

只是想评论“内容类型”位存在,因为它是一个 CGI 脚本。根据 CGI 标准,脚本应首先输出其内容的内容类型,以便 Web 服务器可以决定要做什么。大多数只是将 Content-type 标头与 CGI 程序的输出一起传递给客户端。请参阅en.wikipedia.org/wiki/Common_Gateway_Interface#Output_format 以供参考。此外,PHP 的虚函数将是一种无需获取 Content-type 的方法(它通过 Apache 路由请求)。听起来您的环境中已禁用该功能。 @CalebD,感谢您提供更多信息。如果我可以在我的服务器上对其进行测试,我会将其添加到我的答案中。【参考方案4】:

像 apache2 一样执行 CGI 怎么样??

我经常在 PHP5 中封装二进制 CGI,没有任何问题。

您需要通过在 exec() 之前放置一些 putenv() 指令来模拟 Web 服务器调用,并使用 exec() 和 3 个给定参数(以检查返回值是否为 0)。

putenv() 可用于建立与 apache2 提供 CGI 完全相同的环境——它也适用于传递 URL 参数。

如果一个人可以选择用一种语言写作肯定会更好 -

但有些场景需要接口 - 是否只需要创建 I/O 包装器。

如果你不能以这种方式成功 - 如果你用 cURL 调用 cgi, apache2 将通过调用创建所需的环境。 这可能比要求的更复杂 - 更像是最后的手段。

对不起,我不能提供一个例子,可能足以说明它是如何工作的。

相反,我们正在寻找一种从 CGI 执行 PHP 的方法:)

【讨论】:

【参考方案5】:
<?php
$cgi = exec_cgi("path to cgi");
$cgi->addParameter->contentType("typeofcode");
?>

【讨论】:

【参考方案6】:

为我工作

<?
echo "sometextadd".shell_exec( "/dirtofile/filecontaincgi.cgi  | 

#commandinssh as sed 's/.*$/&<\/TR><TD>/' | and other

")."sometextadd";

?>

【讨论】:

【参考方案7】:

我从这里得到了以下对我有用的解决方案:link

为了方便而转储代码:

    <?php
    $data = file_get_contents("http://fullpathto.cgi",0);
    echo $data;
    ?>

设置是在zend server + unix box上运行的C++编译的.cgi模块

【讨论】:

以上是关于无法在 PHP 文件中包含/执行 CGI 文件的主要内容,如果未能解决你的问题,请参考以下文章

在可执行文件中包含引用

无法在我的 PHP 应用程序中包含名为“config.php”的文件(它会被忽略)

如何在可执行文件中包含带有 pyinstaller 的特定 .jar 文件?

在可执行的 .jar 文件中包含 excel

在UWP最终包中包含可执行文件

执行 java.io.File 或 FileInputStream 时如何引用 OSGi 包中包含的文件