# Web-servers && .htaccess ## PHP Исторически **PHP** работал, используя **CGI**, Common Gateway Interface. При каждом запросе **веб-сервер**: - Принимал соединение, определял по адресу или конфигурации, что данный запрос является **CGI** - Создавал набор переменных окружения (например данные в `$_SERVER` попадают из переменных окружения) с характеристиками запроса - Запускал процесс, обрабатывающий **CGI** запрос, передавая ему на стандартный ввод тело **HTTP** запроса - Процесс обрабатывал **HTTP** запрос, стандартный вывод процесса перенаправлялся **веб-сервером** клиенту в браузер. По окончанию обработки запроса процесс прекращал свою работу. Именно из **CGI** **PHP** унаследовал модель работы *Designed To Die*. ### Современные интерфейсы между **PHP** и **веб-сервером** #### FastCGI **FastCGI** - современная, улучшенная версия **CGI**, в которой: - Для ускорения обработки запросов *процессы не запускаются при каждом запросе, а постоянно работают, обрабатывая множество запросов* - Общение с процессом происходит не через стандартные потоки ввода-вывода, а через сокеты (сетевые соединения или сокеты в файловой системе), что позволяет разнести **FastCGI** процессы на множество других серверов Однако некоторые недостатки **FastCGI** привели к появлению... #### PHP FastCGI Process Manager (php-fpm) Улучшенный **FastCGI**. Этот способ в основном используется в связке с **nginx** #### `mod_php` Классика, самый обычный способ конфигурации **PHP** с **веб-сервером** **Apache**. Кодовая база **PHP** подключается как модуль **веб-сервера** и работает "изнутри" веб-сервера. Достоинство этого подхода в простоте настройки и скорости работы. Недостатки же вытекают из достоинств: слабая масштабируемость, зависимость от **веб-сервера**, меньшая безопасность, отсутствие возможности гибко конфигурировать версии **PHP**. ## Apache Часто используемый для обычных проектов и разработки **веб-сервер**. **PHP** обычно неплохо работает с настройками по умолчанию. ### Основные настройки Для подключения **PHP** в настройках где-то (обычно в /etc/apache2/) должна быть следующая строка, или строка, подобная этой: ``` LoadModule php5_module modules/mod_php.so ``` Эти же строки добавляют связь между расширением файла и модулем php для обрабоки этих файлов: ``` SetHandler application/x-httpd-php ``` `DirectoryIndex` указывают **веб-серверу**, что кроме `index.html` нужно обрабатывать и `index.php`: ``` DirectoryIndex index.php index.phtml ``` ### Virtual mass hosting Работает как модуль mod_vhost_alias. Перед настройкой убедитесь что этот модуль подключен. Обычно в дистрибутивах linux с apache домены настраиваются путем копипасты конфига домена в папке на подобие /etc/apache2/sites.d/. Возможна так же папка /etc/apache2/sites.enabled.d/ в которой хранятся симлинки на включенные сайты. Сайты из sites.d без симлинка в этой папке выключены. Enabled сайты подключаются в основной конфиг apache через директиву Include (в конце файла). Однако есть **альтернатива**: **Virtual mass hosting**. Этот способ отличается упрощенным созданием и удалением доменов. Работает он благодаря следующим возможностям **DNS** и **apache2**: - В DNS конфигурации прописывается звездочка для поддомена: *.dev.galera.com ссылается на IP-адрес вашего сервера с apache2. Таким образом *любой* поддомен типа superproject.dev.galera.com будет адресован на один сервер. - На этом сервере имя поддомена превращается в имя папки, из которой беруться файлы сайта. ``` # get the server name from the Host: header UseCanonicalName Off # this log format can be split per-virtual-host based on the first field # using the split-logfile utility. LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon CustomLog "logs/access_log" vcommon # include the server name in the filenames used to satisfy requests VirtualDocumentRoot "/www/hosts/%0/docs" VirtualScriptAlias "/www/hosts/%0/cgi-bin" ``` Вместо $0 подставляется имя сервера из HTTP-заголовка. Таким образом создание нового поддомена для проекта сводится к созданию директории с именем домена. Есть так же другие переменные, %1, %2 и так далее: - %1 - первый поддомен ("www" в "www.google.com", "superproject" в "superproject.dev.galera.com") - %2 - второй поддомен ("google" в "www.google.com", "dev" в "superproject.dev.galera.com") Таким образом вы можете использовать более удобные имена директорий. Подробнее: https://httpd.apache.org/docs/2.4/vhosts/mass.html ### `.htaccess` Эти файлы являются способом установки локальных настроек для директории и её поддиректорий. Синтаксис в них такой же как и в других конфигах **apache**. Для изменения настроек **PHP** вы можете использовать директиву `php_value` согласно синтаксису `php.ini`. #### `mod_rewrite` Еще один модуль **apache** для отвязывания адреса URL от реальной файловой системы. Часто вызывает боль при попытках отладить сложные конфигурации. Для отладки можно включить логгирование, но **только** при конфигурировании `mod_rewrite` в конфиге **apache**, а не в `.htaccess`. Данную опцию надо занести в конфиг виртуального хоста, поэтому он несовместим с Mass Virtual Hosting: ``` LogLevel alert rewrite:trace3 ``` Умолчательный .htaccess для перенаправления всех запросов к index.php для дальнейшего роутинга средствами MVC-фреймворка: ``` RewriteEngine on # If a directory or a file exists, use the request directly RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # Otherwise forward the request to index.php RewriteRule . index.php [L] ``` **Учтите**, что для работы .htaccess вы должны разрешить изменения конфигурации для конкретной директории. Делается это с помощью следующих настроек веб-сервера в секции Directory: ``` AllowOverride all Require all granted ``` Однако в целом **Apache** изначально задуман для отображения папок реальных файлов, и данные костыли выглядят чужеродно. Более органичен для таких целей **NGINX** и **PHP-FPM**. ## NGINX Легковесный быстродействующий веб-сервер, популярный для высоконагруженных решений. Конфигурация скорее настраивает доменные имена и их обработчики, чем файлы и директории. В этом контексте **NGINX** является **reverse-proxy**, т. е. фасадом перед реальным веб-сервером, обрабатывающим запросы. Тем не менее NGINX без проблем раздает файлы и может сильно оптимизировать раздачу статики и загрузку файлов. На данный момент в NGINX даже есть внутренний скриптовый язык, базированный на **JS**. ### `php-fpm` Типичная конфигурация **nginx+php** реализуется через **php-fpm**. В отличие от **Apache**, в котором **mod_php** является частью процесса веб-сервера, при работе с **php-fpm** нужно два процесса (демона), которые обрабатывают запросы. Первый - **веб-сервер**, который обрабатывает входящие запросы, привязывает веб-приложение к домену, зачастую отдает статические файлы и так далее. Второй процесс - сервер приложения, к которому **веб-сервер** обращается для обработки запросов. #### Конфигурация `php-fpm` Файл php-fpm.conf хранит основные настройки: ``` user = nobody group = nobody listen = 127.0.0.1:9000 pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 ``` - `user,group` - пользователь и группа, из под которых будет запускаться сервер приложений - `listen` - адрес и порт. Обычно используется 127.0.0.1 для безопасности. Запомните эти параметры. - pm... - настройки процессов, количество обработчиков запросов и т. д. #### NGINX ``` server { listen 164.138.30.21; //внешний IP server_name yieldmap.helium.asmer.org.ua; //домен root /var/www/gorobets/yieldmap.helium.asmer.org.ua; //DocumentRoot location / { //корень сайта try_files $uri $uri/ /index.php; autoindex on; } location ~ \.php$ { //все PHP на fpm include /etc/nginx/fastcgi.conf; fastcgi_pass unix:/run/php-fpm.socket; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; } } ``` параметром `fastcgi_pass` указывается сокет в файловой системе (или сетевой, 127.0.0.1:9000, например) ## `php.ini` Это файл конфигурации собственно php. Большинство настроек можно узнать используя `phpinfo()` в коде. > Учтите, что для каждого варианта запуска php скорее всего будет *свой* php.ini. Т. е. настройки, которые работают в консоли, вовсе не обязательно что совпадают с mod_php или php-fpm. Важные конфигурационные параметры: ``` short_open_tag = Off ``` Опция включает или выключает короткие php-тэги `` ``` max_execution_time = 30 ``` время работы скрипта. Имеет смысл для разгрузки веб-серерва и никакого смысла для работы скриптов в консоли. ``` memory_limit = 128M ``` Лимит памяти. Может грохнуть скрипт, который ворочает большим объемом данных, например генерирует прайс в xls, или ORM по большому набору данных в БД. ``` error_reporting = E_ALL ``` Какие ошибки логгировать. ``` display_errors = On ``` Показывать ошибки в выводе или нет. Удобно видеть ошибки в перемешку с HTML при отладке, но недопустимо в продакшене. ``` log_errors = On ``` Опция полезна для записи ошибок в лог-файл на продакшене ## `Forbidden` и права доступа Учтите, что для работы вашего проекта, нужно что бы файлы были доступны для соответственного процесса. Например, если вы отдаете статику с помощью **NGINX**, а php обрабатываете через **php-fpm**, вы должны удостовериться, что у этих процессов доступ к статическим и PHP-файлам соответственно. ## Логи Логи - это важно и интересно. Обычно находятся в `/var/log/apache*/*`, `/var/log/nginx/*`, `/var/log/php*/*`