2

所以我正在编写一个 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 模式下运行,它会很好地工作 - 生成页面和所有内容。

我需要知道的是:

  1. 为 php-cgi 设置 CGI 环境变量以找到我的脚本的正确方法是什么。
  2. 从 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 的某种组合可能会起作用。

4

1 回答 1

0

搞砸的事情是 php.ini 中“doc_root”的设置。我像这样取消设置:

doc_root =

现在 cgi 环境变量的工作方式更像 CGI 规范所说的那样。例如。下面的事情现在有效:

export GATEWAY_INTERFACE="CGI/1.1"
export SERVER_PROTOCOL="HTTP/1.1"
export SCRIPT_FILENAME="/home/rafael/web/cgi-bin/test.php"
export SCRIPT_NAME="test.php"
export REDIRECT_STATUS="200"

/usr/bin/php5-cgi test.php
于 2012-07-19T12:55:31.900 回答