【发布时间】:2012-07-14 22:19:26
【问题描述】:
所以我正在编写一个 Web 服务器(我知道,就像世界需要另一个服务器一样!)我想通过 CGI 调用 php。例如,我有一个运行良好的 CGI1.1 实现,足以运行 perl cgi 脚本。
现在我想运行 php。但是当我的 cgi 模块调用 php 程序时,它会返回 404。
我如何让它工作?
详情:
我在 ubuntu 上运行 php5。在我的 Web 服务器中,我将 cgi 请求传递给处理程序,该处理程序将找到程序并使用脚本作为参数调用它。所以这里是生成 cgi 进程的代码:
chdir( dir );
execve( argv[0], argv.data(), (char* const*) req.posixEnv() );
我运行的命令相当于:
/usr/bin/php5-cgi /home/rafael/webserver/data/cgi-bin/test.php
这意味着我已将“dir”设置为:
/home/rafael/webserver/data/cgi-bin
cgi 进程应该在该目录中运行。 argv[0] 是“/usr/bin/php5-cgi”,argv.data() 返回一个以 null 结尾的数组,其中包含以下元素:
/usr/bin/php5-cgi
/home/rafael/webserver/data/cgi-bin/test.php
NULL
进程环境包含 CGI 环境,其中包含一组常用 CGI 环境变量。
当我从 shell 运行上述命令时,也就是将其直接输入到 shell 中,脚本运行良好,php 生成测试页面。当我从 CGI 调用它时,它会返回:
Status: 404 Not Found
X-Powered-By: PHP/5.3.10-1ubuntu3.2
Content-type: text/html
No input file specified.
现在我或多或少知道发生了什么。 PHP 正在检测它是在 CLI 还是 CGI 模式下运行,并搜索脚本以在每种模式下以不同的方式运行。在 CGI 模式下,它可能使用 SCRIPT_FILENAME 和 DOCUMENT_ROOT 等 CGI 环境变量来解析脚本名称。我已经尝试了很多东西 - 这些变量的不同设置。但是这些都不起作用。
我所知道的:PHP 的整个产生和读取输出工作。例如,如果我删除某些 CGI 变量,使其认为它在 CLI 模式下运行,它会很好地工作 - 生成页面和所有内容。
我需要知道的是:
- 为 php-cgi 设置 CGI 环境变量以找到我的脚本的正确方法是什么。
- 从 exec 调用 php 脚本的正确方法是什么。我正在对所有内容使用完整路径来调试它。我更喜欢使用相对路径。
我能找到的所有文档都是关于在特定 Web 服务器上为 cgi 配置 php。我需要从编写服务器的人的角度来了解这一点。
@EDIT:我有一个更简单的例子,它消除了 c++。我很确定那部分工作正常。假设我编写了一个调用 php-cgi 的脚本,并尝试在 shell 中模拟 cgi 调用约定。
这行得通:
#export GATEWAY_INTERFACE="CGI/1.1"
export REDIRECT_STATUS=200
export SERVER_PROTOCOL="HTTP/1.1"
export DOCUMENT_ROOT="/home/rafael/web"
#export SCRIPT_FILENAME="cgi-bin/test.php"
export SCRIPT_NAME="cgi-bin/test.php"
/usr/bin/php5-cgi test.php
但这不是:
export GATEWAY_INTERFACE="CGI/1.1"
export REDIRECT_STATUS=200
export SERVER_PROTOCOL="HTTP/1.1"
export DOCUMENT_ROOT="/home/rafael/web"
#export SCRIPT_FILENAME="cgi-bin/test.php"
export SCRIPT_NAME="cgi-bin/test.php"
/usr/bin/php5-cgi test.php
我认为 DOCUMENT_ROOT、SCRIPT_FILENAME 和 SCRIPT_NAME 的某种组合应该可以工作。
【问题讨论】:
标签: php c++ web-services web-applications cgi