Я пытаюсь установить предыракский всплеск 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: #
и т.п.
Превосходно!
Однако вызов 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 application/x-httpd-php
.
Если PHP должен запускаться через соглашения CGI, то исполняемый файл будет запускаться всякий раз, когда файл с типом MIME application/x-httpd-php
запрашивается обозначается с помощью Действие. В ScriptAlias дает 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
)
Это безумие, но я нашел следующее решение:
Создать скрипт redirect.pl
(который, конечно, также может быть небольшим двоичным файлом), чтобы "обернуть" php
исполняемый файл (обратите внимание, что нет php-cgi
в PHP 4.4.9).
Скрипт вызывается из 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 Httpd устанавливает для исполняемого файла CGI, если index.php
запрашиваются:
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
так оно и есть?
В Документация Apache для обработчиков говорит, что на первоначально запрошенный документ указывает переменная среды PATH_TRANSLATED. Он не упоминает SCRIPT_FILENAME.
В CGI RFC 3875 также не упоминает SCRIPT_FILENAME. С другой стороны, ваши примеры показывают, что используемый вами php-cgi ожидает имя файла PHP в SCRIPT_FILENAME. Похоже, это зависит от неопределенного поведения.
Обратите внимание, что PHP 4.4.9 довольно старый, а сервер Apache, который вы используете, вероятно, новее. Так что возможно, что Apache с того времени передал имя файла сценария (также) в SCRIPT_FILENAME, и с тех пор поведение изменилось.
Вам не нужен perl для назначения переменной окружения, простой скрипт scell тоже подойдет, но используйте то, что вам удобно.
#!/bin/sh SCRIPT_FILENAME=$PATH_TRANSLATED exec /usr/local/php-4.4.9/bin/php