我正在尝试安装伊拉克增兵前4.4.9 PHP在现代Apache 2.4.6并希望以 CGI 模式运行它。
当前配置如下:
PHP 可执行文件是/usr/local/php-4.4.9/bin/php
$documentroot/phphere/index.php
虚拟服务器中存在一个测试文件,它包含:
<?php
phpinfo();
?>
如果我执行index.php
使用php
,则一切都顺利。
跑步
/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: #
ETC。
出色的!
但是,index.php
通过 Web 客户端调用会导致以下结果:
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
如果我理解正确的话,添加类型.php
标记任何以 MIME 类型结尾的文件application/x-httpd-php
。
如果 PHP 应通过 CGI 约定运行,则每当application/x-httpd-php
请求具有 MIME 类型的文件时,要运行的可执行文件将用行动。 这脚本别名给出可执行文件的目录的 URL 路径php
。(这个语法听起来很别扭,为什么不用一个命令来实现呢?)
此外,该选项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
)
答案1
这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 脚本也可以,但请使用您熟悉的脚本。
/bin/sh #!/bin/sh 复制代码 SCRIPT_FILENAME=$PATH_TRANSLATED exec /usr/local/php-4.4.9/bin/php
答案2
这完全是疯狂的,但我找到了以下解决方案:
创建一个脚本redirect.pl
(当然也可以是一个小的二进制文件)来“包装”可执行文件(请注意, PHP 4.4.9 中php
没有)。php-cgi
该脚本从Apache httpd经过:
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/redirect.pl
脚本的完整路径名是/usr/local/php-4.4.9/bin/redirect.pl
;它只是执行以下操作:
#!/usr/bin/perl
use strict;
use warnings;
my $phpfile = $ENV{PATH_TRANSLATED};
my $phpexe = $ENV{SCRIPT_FILENAME};
$ENV{SCRIPT_FILENAME} = $phpfile;
exec "/usr/local/php-4.4.9/bin/php";
为什么会出现上述情况?环境变量Apache Httpdindex.php
如果请求,则 CGI 可执行文件的设置如下:
PATH_TRANSLATED = /var/www/html/myserver.example.com/phphere/index.php
SCRIPT_FILENAME = /usr/local/php-4.4.9/bin/php
从经验上看,这php
只会执行其自身,即php
假定SCRIPT_FILENAME
包含 PHP 脚本的文件名,并有一定的道理。
因此我们需要上面的脚本将 的值设置SCRIPT_FILENAME
为 的值PATH_TRANSLATED
。
现在的问题是,为什么Apache Httpd设置它的价值的SCRIPT_FILENAME
方式呢?