无法在 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) <?php include("script.cgi"); ?>
结果:没有执行。这只是打印出 CGI 文件的全部内容,就好像它只是一个文本文件一样。
2)<?php virtual("script.cgi"); ?>
结果: Fatal error: Call to undefined function virtual() in test.php on line #
.
这让我很困扰,因为我阅读的所有内容都表明这是正确的做法。我不是 PHP 专家,但 virtual
怎么可能是“未定义函数”? listed in the official PHP docs 对 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,老实说,我不知道,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”的文件(它会被忽略)