Установка PHP как FastCGI под Apache (Windows 10)
Но, поскольку у меня 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 :
"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
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 # 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 # # localhost1 # 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 # # localhost2 # 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 # # localhost3 # 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
Для каждого виртуального хоста добавляем одну строчку, которая переопределяет переменную среды PHPRC . После этого берем дефолтный php.ini из директории C:/wamp/php71 и копируем в директорию каждого хоста. У меня это
В каждом файле 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 # 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 "d:/work/localhost4/www"> FcgidWrapper "c:/wamp/php56/php-cgi.exe" .php ErrorLog d:/work/localhost4/error.log CustomLog d:/work/localhost4/access.log common
У меня 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
Дополнительно
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.
- 1С:Предприятие (31)
- API (29)
- Bash (43)
- CLI (99)
- CMS (139)
- CSS (50)
- Frontend (75)
- HTML (66)
- JavaScript (150)
- Laravel (72)
- Linux (146)
- MySQL (76)
- PHP (125)
- React.js (66)
- SSH (27)
- Ubuntu (68)
- Web-разработка (509)
- WordPress (73)
- Yii2 (69)
- БазаДанных (95)
- Битрикс (66)
- Блог (29)
- Верстка (43)
- ИнтернетМагаз… (84)
- КаталогТоваров (87)
- Класс (30)
- Клиент (27)
- Ключ (28)
- Команда (68)
- Компонент (60)
- Конфигурация (62)
- Корзина (32)
- ЛокальнаяСеть (28)
- Модуль (34)
- Навигация (31)
- Настройка (140)
- ПанельУправле… (29)
- Плагин (33)
- Пользователь (26)
- Практика (99)
- Сервер (74)
- Событие (27)
- Теория (105)
- Установка (66)
- Файл (47)
- Форма (58)
- Фреймворк (192)
- Функция (36)
- ШаблонСайта (68)
PHP → Коротко о CGI, FastCGI, PHP-FPM и mod_php
Решил навести в голове порядок о том, как работают вместе веб-сервер и PHP.
CGI
Common Gateway Interface, «общий интерфейс шлюза» — это стандарт, который описывает, как веб-сервер должен запускать прикладные программы (скрипты), как должен передавать им параметры HTTP-запроса, как программы должны передавать результаты своей работы веб-серверу. Прикладную программу взаимодействующую с веб-сервером по протоколу CGI принято называть шлюзом, хотя более распространено название CGI-скрипт или CGI-программа.
В качестве CGI-программ могут использоваться программы/скрипты написанные на любых языках программирования, как на компилируемых, так и на скриптовых, в том числе на shell.
CGI-скрипты были популярны до того, как для веб-разработки стали преимущественно использовать PHP. Хотя сам PHP интерпретатор позволяет работать в режиме CGI (см. ниже).
Основной момент: «CGI» это не язык программирования и не отдельная программа! Это просто протокол (стандарт, спецификация, соглашение, набор правил).
FastCGI
Дальнейшее развитие технологии CGI, является более производительным и безопасным, снимает множество ограничений CGI-программ.
FastCGI программа работает следующим образом: программа единожды загружается в память в качестве демона (независимо от HTTP-сервера), а затем входит в цикл обработки запросов от HTTP-сервера. Один и тот же процесс обрабатывает несколько различных запросов один за другим, что отличается от работы в CGI-режиме, когда на каждый запрос создается отдельный процесс, «умирающий» после окончания обработки.
Написание FastCGI программ-демонов сложнее чем CGI, нужны дополнительные библиотеки, зависящие от языка.
Опять же, сама аббревиатура FastCGI это не язык программирования и не отдельная программа, это как и в случае CGI — просто спецификация.
PHP в режиме CGI
PHP в режиме CGI это самый старый способ выполнения php-скриптов веб-сервером. Режим доступен по умолчанию, однако может быть отключён при компиляции.
Для Apache нужен модуль mod_cgi (поставляется вместе с Apache). Nginx из коробки поддержки не имеет, хотя существуют дополнительные инструменты.
В данный момент режим используется редко в силу малой производительности.
PHP в режиме FastCGI
Помимо CGI режима, PHP из коробки умеет работать и в FastCGI режиме (с версии 5.3 даже в двух FastCGI режимах). Режим включается флагом при компиляции интерпретатора, флаг зависит от версии PHP.
Для работы с Apache нужен модуль mod_fcgid или mod_fastcgi, либо связка из mod_proxy_fcgi + PHP-FPM.
Nginx умеет работать с FastCGI приложениями из коробки, но именно для PHP дополнительно нужен PHP-FPM (см. ниже).
Следует помнить, что при работе PHP в режиме FastCGI в памяти висит сам php интерпретатор, а не какой-то конкретный php-скрипт.
PHP-FPM
FastCGI Process Manager, «Менеджер процессов FastCGI». Это альтернативная реализация FastCGI режима в PHP с несколькими дополнительными возможностями, которые обычно используются для высоконагруженных сайтов.
Изначально PHP-FPM представлял из себя набор патчей от Андрея Нигматулина, которые устраняли ряд проблем, мешающих полноценно использовать PHP в режиме FastCGI (список улучшений). С версии PHP 5.3 набор патчей включён в ядро, а дополнительные возможности PHP-FPM включаются флагом при компиляции.
PHP-FPM используется в основном в связке с Nginx, без установки Apache.
mod_php
Это модуль для Apache, позволяющий ему выполнять php скрипты. Является наверно самым популярным и простым способом подружить Apache и PHP. Модуль не использует ни CGI, ни FastCGI. Есть свои минусы — скрипты работают под пользователем веб-сервера, невозможно использовать больше одной версии PHP.