Конфигурация nginx, которая позволяет удалять index.php из URL и передавать pathinfo в скрипты index.php, но не в другие php скрипты.

Вопрос или проблема

У меня не так много опыта с 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 скрипты не должны.
  • Если index.php явно упоминается в URL, он не должен выполняться.
  • Если URL включает несколько каталогов, каждый из которых содержит index.php, то последний из них должен быть скриптом, который обрабатывает запрос.
  • Запрос для 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

  1. Создайте резервную копию конфигурации: Перед внесением изменений в конфигурацию вашего сервера, убедитесь, что вы создали резервную копию текущего файла конфигурации Nginx:

    sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
  2. Редактирование конфигурации: Откройте файл конфигурации вашего сайта в Nginx. Обычно это файл в /etc/nginx/sites-available/. Например:

    sudo nano /etc/nginx/sites-available/example.com.conf
  3. Базовая структура конфигурации: Добавьте следующий блок в ваш конфигурационный файл. Это пример блока 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 и структуры вашего приложения, поэтому их нужно дополнительно подстроить, если что-то не работает как ожидал.

Оцените материал
Добавить комментарий

Капча загружается...