我正在尝试在现代Apache 2.4.6中安装 pre-Iraq-Surge 4.4.9 PHP ,并希望在 CGI 模式下运行它。
当前配置如下:
PHP 可执行文件是/usr/local/php-4.4.9/bin/php
虚拟服务器中存在一个测试文件$documentroot/phphere/index.php
,它包含:
<?php
phpinfo();
?>
如果我执行index.php
using php
,一切都是 hunky dory。
跑步
/usr/local/php-4.4.9/bin/php $documentroot/phphere/index.php | less
产量
X-Powered-By: PHP/4.4.9
Content-type: text/html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html><head>
<style type="text/css">
body {background-color: #ffffff; color: #000000;}
body, td, th, h1, h2 {font-family: sans-serif;}
pre {margin: 0px; font-family: monospace;}
a:link {color: #000099; text-decoration: none; background-color: #
等等
出色的!
但是,通过 Web 客户端调用index.php
会导致:
Warning: Unexpected character in input: '' (ASCII=1) state=1 in /usr/local/php-4.4.9/bin/php on line 277
Warning: Unexpected character in input: '' (ASCII=15) state=1 in /usr/local/php-4.4.9/bin/php on line 277
Parse error: syntax error, unexpected T_STRING in /usr/local/php-4.4.9/bin/php on line 277
如果一个人自己处理php可执行文件,这正是一个人得到的输出,即输出
/usr/local/php-4.4.9/bin/php /usr/local/php-4.4.9/bin/php
(减去额外生成的任何标题)。
好的,所以 Apache 设置中存在一些问题。但是什么?
配置如下:
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
ScriptAlias /outsidephp /usr/local/php-4.4.9/bin
Action application/x-httpd-php /outsidephp/php
如果我理解正确,AddType会标记任何.php
以 MIME type结尾的文件application/x-httpd-php
。
如果 PHP 应通过 CGI 约定运行,则每当application/x-httpd-php
请求具有 MIME 类型的文件时运行的可执行文件用Action指示。ScriptAlias给出了php
可执行文件所在目录的URL 路径。(虽然这种语法听起来很尴尬,为什么没有一个命令呢?)
此外,该选项ExecCGI
已在包含的目录中设置,index.php
并且该文件系统树上的 SELinux 上下文标有httpd_sys_script_exec_t
.
请注意,绝对没有
AddHandler cgi-script .php
在配置中,因为这使 Apache 尝试.php
直接执行以脚本结尾的文件,这可以预见地失败并出现错误 500:
Error message:
End of script output before headers: index.php
究竟出了什么问题?
如何让 Apache 运行
php index.php
代替
php php
(即很可能php php index.php
)
这完全是疯狂的,但我找到了以下解决方案:
创建一个脚本
redirect.pl
(当然也可以是一个小的二进制文件)来“包装”php
可执行文件(注意php-cgi
PHP 4.4.9 中没有)。该脚本通过以下方式从Apache httpd调用:
脚本的完整路径名是
/usr/local/php-4.4.9/bin/redirect.pl
; 它只是这样做:为什么是上面的?如果需要, Apache Httpd为 CGI 可执行文件设置的环境变量
index.php
是:从经验上讲,这
php
只是执行本身,即php
假设SCRIPT_FILENAME
包含 PHP 脚本的文件名,并有一些理由。因此,我们需要上面的脚本将 的值设置
SCRIPT_FILENAME
为 的值PATH_TRANSLATED
。现在的问题是,为什么Apache Httpd设置它的值
SCRIPT_FILENAME
的方式呢?处理程序的Apache 文档说最初请求的文档由 PATH_TRANSLATED 环境变量指向。它没有提到 SCRIPT_FILENAME。
CGI RFC 3875也没有提到 SCRIPT_FILENAME 。另一方面,您的示例表明您正在使用的 php-cgi 需要 SCRIPT_FILENAME 中的 PHP 文件的名称。这似乎依赖于未定义的行为。
请注意,PHP 4.4.9 相当旧,而您使用的 Apache 服务器可能较新。因此,从那时起,Apache 有可能在 SCRIPT_FILENAME 中传递了脚本文件的名称(也),并且从那时起行为发生了变化。
您不需要 perl 来分配环境变量,一个简单的 scell 脚本也可以,但请使用您喜欢的。