【问题标题】:How to call php-cgi from c++如何从 C++ 调用 php-cgi
【发布时间】: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 模式下运行,它会很好地工作 - 生成页面和所有内容。

我需要知道的是:

  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 的某种组合应该可以工作。

【问题讨论】:

    标签: php c++ web-services web-applications cgi


    【解决方案1】:

    搞砸的是 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2016-12-17
      • 2018-08-04
      • 2011-02-04
      相关资源
      最近更新 更多