Вопрос или проблема
У меня не так много опыта с nginx (хотя у меня много опыта с apache и веб-сервисами в общем).
Мои требования изложены ниже. Мне пока не удалось собрать конфигурацию, которая бы соответствовала им всем. Я, конечно, почитал документацию, погуглил и немного поэкспериментировал, и мне удалось выяснить несколько различных способов удовлетворить некоторые, но не все из них. Я колеблюсь между пробами и ошибками, потому что не знаю достаточно о nginx, чтобы оценить качество любого решения, которое я мог бы придумать.
Некоторые из конкретных проблем, с которыми я столкнулся, включают получение PATH_INFO, когда URL явно содержал index.php, но не в противном случае, обработка запроса с помощью /index.php, когда он существует, но я хочу, чтобы его обрабатывал более глубоко вложенный, например /foo/index.php, и сценарий, обрабатывающий запрос, в котором path_info включает существующий каталог, но заканчивается несуществующим подкаталогом или файлом (случай, когда я хочу получить 404). Это не исчерпывающий список проблем, с которыми я столкнулся.
Я буду очень признателен за полное решение, но буду рад любым ответам, которые приблизят меня к цели.
Пример структуры сайта:
…/assets/css/site.css
…/index.php
…/gallery/index.php
…/script.php
- Индексные каталоги будут включать index.php и index.html.
- Если скрипт index.php обрабатывает запрос, но не указан явно в URL, он должен получать pathinfo.
- https://example.com/foo/bar должен обрабатываться …/index.php и получать “/foo/bar” как pathinfo.
- Только файлы index.php должны получать pathinfo; другие php скрипты не должны.
- https://example.com/script.php/foo/bar должна вернуть 404.
- Если index.php явно упоминается в URL, он не должен выполняться.
- https://example.com/index.php/foo/bar должна вернуть 404.
- Если URL включает несколько каталогов, каждый из которых содержит index.php, то последний из них должен быть скриптом, который обрабатывает запрос.
- https://example.com/gallery/foo/bar должен обрабатываться …/gallery/index.php и получать /foo/bar как pathinfo.
- Запрос для URL, содержащего каталог, который реально существует, но не имеет своего собственного index.php, не должен обрабатываться скриптом вообще.
- https://example.com/assets/css не должен обрабатываться …/index.php; он должен вернуть 404, потому что он существует, но не имеет индекса.
- https://example.com/assets/foo не должен обрабатываться …/index.php; он должен вернуть 404, потому что …/assets существует, но не имеет индекса.
Ответ или решение
Для настройки веб-сервера Nginx с учетом ваших требований, приведенных в вопросе, потребуется создать конфигурационный файл, который будет обрабатывать определенные сценарии, связанные с файлами index.php
, пути и 404 ошибками. Ниже приведена подробная инструкция по созданию такой конфигурации.
Шаги настройки Nginx
-
Создайте резервную копию конфигурации: Перед внесением изменений в конфигурацию вашего сервера, убедитесь, что вы создали резервную копию текущего файла конфигурации Nginx:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
-
Редактирование конфигурации: Откройте файл конфигурации вашего сайта в Nginx. Обычно это файл в
/etc/nginx/sites-available/
. Например:sudo nano /etc/nginx/sites-available/example.com.conf
-
Базовая структура конфигурации: Добавьте следующий блок в ваш конфигурационный файл. Это пример блока
server
, который включает все необходимые правила:server { listen 80; server_name example.com; root /path/to/your/webroot; index index.php index.html; location / { # 404 для всех существующих директорий без index.php try_files $uri $uri/ =404; # Обработка всех запросов к index.php if ($request_uri !~ /index\.php/) { set $path_info ''; rewrite ^/(.*)$ /index.php?$path_info=$1 last; # Дополнительная проверка, чтобы, если путь ведет на существующий файл или директорию, не обрабатывать. } } location ~ \.php$ { # Отключаем для любых php файлов, кроме index.php if ($request_uri ~ /index\.php/) { # Исполняем index.php если он явно указан в URI return 404; } return 404; # Для всех других PHP скриптов } location ~ /gallery/ { try_files $uri $uri/ /gallery/index.php?$path_info=$uri; # Переход к gallery/index.php } # PHP обработка location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # Замените на ваш актуальный файл сокета fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $path_info; include fastcgi_params; } }
Объяснение конфигурации
-
Раздел server: Содержит основной набор директив для обработки запросов, включая
listen
,server_name
иroot
, указывающие серверу, на каком порту и для какого домена он будет работать. -
Директива index: Указывает, что
index.php
иindex.html
будут служить индикаторами для корневых директорий. -
Обработчик запросов:
try_files $uri $uri/ =404;
— эта строка пытается найти запрашиваемый URI и, если он не существует, возвращает ошибку 404.- Правила с использованием
if
иrewrite
позволяют обрабатывать ситуации, когда пользователь запрашивает URL безindex.php
, передавая нужные параметры вindex.php
.
-
Ограничение на обработку других PHP файлов: Если в запросе используется
index.php
, то сервер возвращает 404. Для остальных PHP файлов также возвращается 404. -
Глобальная обработка и передача PATH_INFO: Все пути, которые содержат
index.php
закрываются, и другие PHP-файлы будут обрабатываться только при необходимости.
Проверка конфигурации и перезапуск сервера
После внесения изменений не забудьте проверить корректность конфигурации:
sudo nginx -t
Если все в порядке, перезапустите Nginx:
sudo systemctl restart nginx
Заключение
Эта конфигурация должна удовлетворить всем указанным вами требованиям. Имейте в виду, что специфические параметры конфигурации могут варьироваться в зависимости от вашей версии PHP и структуры вашего приложения, поэтому их нужно дополнительно подстроить, если что-то не работает как ожидал.