Назад | Перейти на главную страницу

Apache с PHP, работающим в режиме CGI: исполняемый файл php обрабатывается сам, что мне нужно изменить в конфигурации

Я пытаюсь установить предыракский всплеск 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