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

3
使用SSI,我可以简单地将此内容包含在我的HTML文件中,CGI脚本的输出会显示在页面上:
<!--#include virtual="script.cgi"-->

现在我正在尝试做相应的事情,但是不是在HTML文件中,而是在PHP文件中。我已经研究了一整天,但每种方法都给我带来以下问题。我将按我认为可能有效的顺序列出它们,以及较为难以理解的方法...

1) <?php include("script.cgi"); ?>

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


2) <?php virtual("script.cgi"); ?>

结果:致命错误:调用未定义函数virtual(),在test.php的第#行

这让我感到困扰,因为我读到的所有东西都表明这是正确的方法。虽然我不是PHP方面的专家,但virtual怎么可能是一个“未定义的函数”呢?它在官方PHP文档中被列为适用于PHP 5版本的有效函数。


3) <?php exec("script.cgi"); ?>

结果:空的。什么也没有。


4)

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

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


5) <?php echo system("script.cgi"); ?>

结果: 混合。它会执行,但是 CGI 脚本的“结果”会被打印两次,并且前面带有“Content-type: text/html”。我不理解这一点。

Content-type: text/html resultresult

如果删除echo,则结果为...

<?php system("script.cgi"); ?>,结果为...

Content-type: text/html result


6) <?php print("/usr/bin/perl script.cgi"); ?>

结果:未执行。它只是打印出 print 语句后面的内容 (/usr/bin/perl script.cgi)。(我不惊讶,但论坛里有人声称这对他们有效。)


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

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

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


“virtual” 函数仅在 PHP 安装为 Apache 模块时才支持。- PHP 是否安装为 Apache 模块? - deceze
@deceze,老实说我不知道,PHP是预装在这个账户上的。有没有办法可以查看? - Sparky
@ColeJohnson,这个特定的函数可以很容易地转换为PHP,但我真的想知道如何在任何情况下修复它。 - Sparky
@deceze 尝试使用 php_info() 函数查看它是否作为模块安装或仅被调用。 - Cole Tobin
7个回答

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);
?>

0

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

将任何小型CGI/Perl脚本简单重写为PHP不应该太困难。对于那些太大而无法重写的部分,最好还是全部使用Perl。


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

0

尝试

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

不好。结果和我的5b一样。Content-type: text/html result. - Sparky

0

要像apache2一样执行CGI如何?

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

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

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

如果有选择只写一种语言肯定更好-

但是存在需要进行接口的情况- 需要创建I/O封装器。

如果您无法通过此方式成功-如果您使用cURL调用cgi, apache2将通过调用创建所需的环境。 这可能比所需的复杂性更多-更像最后的手段。

很抱歉我无法提供示例,可能告诉它如何工作就足够了。

而是寻找一种从CGI执行PHP的方式,反之亦然:)


0

对我来说这个有效

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

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

}")."sometextadd";

?>

0
<?php
$cgi = exec_cgi("path to cgi");
$cgi->addParameter->contentType("typeofcode");
?>

-2

我从这里得到了以下解决方案,对我很有效:link

为了方便起见,以下是代码转储:

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

安装是在Zend服务器+Unix系统上运行的C++编译的.cgi模块


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接