Установка PHP как FastCGI под Apache (Windows 10)

10.06.2018

Теги: ApacheCGIFastCGIPHPphp.iniSAPIWeb-разработкаWindowsНастройкаУстановка

При установке Битрикс столкнулся с необходимостью изменять настройки PHP в файле php.ini. Например, вот эти

short_open_tag = On
mbstring.func_overload = 2
max_input_vars = 10000

Но, поскольку у меня PHP установлен как модуль Apache, эти изменения затронули все виртуальные хосты. Из-за этого перестал работать phpMyAdmin. Пришлось устанавливать PHP как FastCGI, чтобы для каждого виртуального хоста был свой файл php.ini.

Интерфейс FastCGI — клиент-серверный протокол взаимодействия вебсервера и приложения, дальнейшее развитие технологии CGI. По сравнению с CGI является более производительным и безопасным.

FastCGI ликвидирует множество ограничений CGI-программ. Проблема CGI-программ в том, что они должны быть перезапущены веб-сервером при каждом запросе, что приводит к понижению производительности.

FastCGI убирает это ограничение, сохраняя процесс запущенным и передавая запросы этому постоянно запущенному процессу. Это позволяет не тратить время на запуск новых процессов.

В то время как CGI-программы взаимодействуют с сервером через STDIN и STDOUT запущенного CGI-процесса, FastCGI-процессы используют Unix Domain Sockets или TCP/IP для связи с сервером. Это значит, что FastCGI-программы могут быть запущены не только на этом же сервере, но и где угодно в сети. Также возможна обработка запросов несколькими FastCGI-процессами, работающими параллельно.

Для начала скачиваем модуль mod_fcgid с сайта apachelounge.com, распаковываем и кладем в директорию modules сервера Apache. У меня это C:/wamp/apache/modules. Далее, переходим в директорию apache/conf и вносим изменения в файл конфигурации Apache httpd.conf:

<Directory "d:/work/localhost*/www">
    Options Indexes FollowSymLinks ExecCGI
    AddHandler fcgid-script .php
    FcgidWrapper "c:/wamp/php71/php-cgi.exe" .php
    AllowOverride All
    Require all granted
</Directory>

В конец файла дописываем:

LoadModule fcgid_module modules/mod_fcgid.so
FcgidInitialEnv PHPRC "c:/wamp/php71"

Последняя директива означает, что файл php.ini расположен в директории C:/wamp/php71. Это будет файл конфигурации PHP по умолчанию. Строки, которые отвечают за работу PHP как модуля Apache, удаляем или комментируем:

# PHPIniDir "c:/wamp/php71"
# AddHandler application/x-httpd-php .php
# LoadModule php7_module "c:/wamp/php71/php7apache2_4.dll"

Теперь редактируем файл виртуальных хостов httpd-vhosts.conf. У меня он расположен в C:/wamp/apache/conf/extra:

#
#   localhost
#
<VirtualHost *:80>
    ServerAdmin admin@localhost
    ServerName localhost
    DocumentRoot "d:/work/localhost/www"
    ServerAlias host.ru www.host.ru
    # Переопределяем PHPRC, чтобы у хоста был свой php.ini
    FcgidInitialEnv PHPRC "d:/work/localhost"
    ErrorLog "d:/work/localhost/error.log"
    CustomLog "d:/work/localhost/access.log" common
</VirtualHost>

#
#   localhost1
#
<VirtualHost *:80>
    ServerAdmin admin@localhost1
    ServerName localhost1
    DocumentRoot "d:/work/localhost1/www"
    ServerAlias host1.ru www.host1.ru
    # Переопределяем PHPRC, чтобы у хоста был свой php.ini
    FcgidInitialEnv PHPRC "d:/work/localhost1"
    ErrorLog "d:/work/localhost1/error.log"
    CustomLog "d:/work/localhost1/access.log" common
</VirtualHost>

#
#   localhost2
#
<VirtualHost *:80>
    ServerAdmin admin@localhost2
    ServerName localhost2
    DocumentRoot "d:/work/localhost2/www"
    ServerAlias host2.ru www.host2.ru
    # Переопределяем PHPRC, чтобы у хоста был свой php.ini
    FcgidInitialEnv PHPRC "d:/work/localhost2"
    ErrorLog "d:/work/localhost2/error.log"
    CustomLog "d:/work/localhost2/access.log" common
</VirtualHost>

#
#   localhost3
#
<VirtualHost *:80>
    ServerAdmin admin@localhost3
    ServerName localhost3
    DocumentRoot "d:/work/localhost3/www"
    ServerAlias host3.ru www.host3.ru
    # Переопределяем PHPRC, чтобы у хоста был свой php.ini
    FcgidInitialEnv PHPRC "d:/work/localhost3"
    ErrorLog "d:/work/localhost3/error.log"
    CustomLog "d:/work/localhost3/access.log" common
</VirtualHost>

Для каждого виртуального хоста добавляем одну строчку, которая переопределяет переменную среды PHPRC. После этого берем дефолтный php.ini из директории C:/wamp/php71 и копируем в директорию каждого хоста. У меня это

  • D:/work/localhost
  • D:/work/localhost1
  • D:/work/localhost2
  • D:/work/localhost3

В каждом файле php.ini находим строки

; The root of the PHP pages, used only if nonempty.
; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
; if you are running php as a CGI under any web server (other than IIS)
; see documentation for security issues.  The alternate is to use the
; cgi.force_redirect configuration below
; http://php.net/doc-root
doc_root =

и установливаем значение doc_root:

doc_root = "d:/work/localhost/www"
doc_root = "d:/work/localhost1/www"
doc_root = "d:/work/localhost2/www"
doc_root = "d:/work/localhost3/www"

Теперь у каждого виртуального хоста будет свой php.ini. Осталось только перезапустить Apache, чтобы изменения вступили в силу.

> cd C:/wamp/apache/bin
> httpd.exe -k restart

Разные версии PHP

Если для какого-то проекта нужно использовать другую версию PHP, вносим изменения в файл httpd-vhosts.conf

#
#   localhost4
#
<VirtualHost *:80>
    ServerAdmin admin@localhost4
    ServerName localhost4
    DocumentRoot "d:/work/localhost4/www"
    ServerAlias host4.ru www.host4.ru
    # Переопределяем PHPRC, чтобы у хоста был свой php.ini
    FcgidInitialEnv PHPRC "d:/work/localhost4"
    # Этот хост будет работать с PHP версии 5.6
    <Directory "d:/work/localhost4/www">
        FcgidWrapper "c:/wamp/php56/php-cgi.exe" .php
    </Directory>
    ErrorLog d:/work/localhost4/error.log
    CustomLog d:/work/localhost4/access.log common
</VirtualHost>

У меня PHP 5.6 установлен в директории C:/wamp/php56, поэтому именно оттуда я взял php.ini и скопировал в D:/work/localhost4.

Чуть позже столкнулся с ошибкой при тестировании системы в Битрикс (Настройки • Инструменты • Проверка системы):

Загрузка файла больше 4 Мб: Ошибка! Не работает

Проверил настройки php.ini, связанные с загрузкой файлов:

; загрузка файлов разрешена
file_uploads = On
; максимальный размер загружаемого файла
upload_max_filesize = 32M
; максимальное кол-во загружаемых файлов
max_file_uploads = 20
; максимальный размер POST-данных
post_max_size = 64M
; максимальное время выполнения скрипта
max_execution_time = 600
; ограничение памяти, используемой скриптом
memory_limit = 512M

Вроде все в порядке. Тогда посмотрел еще логи Apache, и там увидел ошибку:

[Sun Jun 10 13:03:33.657355 2018] [fcgid:warn] [pid 6148:tid 1224] [client 127.0.0.1:3954] mod_fcgid:
HTTP request length 135743 (so far) exceeds MaxRequestLen (131072)

Значение по умолчанию FcgidMaxRequestLen равно 131072 байт (128 Кб). Добавил в конец файла httpd.conf:

# максимальный размер данных HTTP-запроса 64 Мб
FcgidMaxRequestLen 67108864
# максимальное время выполнения скрипта 600 сек.
FcgidIOTimeout 600

Этого должно быть достаточно, но есть еще и другие настройки:

  • FcgidFixPathinfo — должно быть 1, если в php.ini параметр cgi.fix_pathinfo выставлен в 1
  • FcgidIOTimeout — максимальное время ожидания ответа от FastCGI приложения
  • FcgidMaxRequestLen — максимальный размер запроса HTTP
  • FcgidMaxProcesses — максимальное количество процессов FastCGI
  • FcgidMinProcessesPerClass — минимальное количество процессов на программу FastCGI
  • FcgidMaxProcessesPerClass — максимальное количество процессов на программу FastCGI
  • FcgidIdleTimeout — если процесс не обрабатывал запросы в течении указанного здесь времени и текущее количество процессов на программу больше, чем FcgidMinProcessesPerClass, то он удаляется
  • FcgidMaxRequestsPerProcess — приложение FastCGI будет уничтожено, после того как обработает указанное здесь количество запросов
  • FcgidPassHeader — запрос, который передается в переменные окружения
  • FcgidProcessLifeTime — максимальное время жизни процесса FastCGI

Дополнительно

Поиск: Apache • CGI • FastCGI • PHP • SAPI • Web-разработка • Windows • php.ini • Установка • Настройка • Виртуальный хост • VirtualHost

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.