所以我正在编写一个 Web 服务器(我知道,就像世界需要另一个服务器一样!)我想通过 CGI 调用 php。例如,我有一个运行良好的 CGI1.1 实现,足以运行 perl cgi 脚本。
现在我想运行 php。但是当我的 cgi 模块调用 php 程序时,它会返回 404。
我如何让这个工作?
细节:
我正在使用 php5 在 ubuntu 上运行。在我的 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() 返回一个包含以下元素的空终止数组:
/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 的某种组合可能会起作用。