Soft2Soft Dev Практическая база знаний
Yii2

Yii2 Pretty URL возвращает 404: пошаговая диагностика Apache и Nginx

15 просмотров
yii2 pretty-url 404 apache nginx

Сначала определите источник 404

Код 404 может появляться на разных уровнях. Веб-сервер может не передать запрос в index.php, либо Yii2 получает запрос, но не находит маршрут.

ПризнакПричинаГде искать
Стандартная страница 404 Apache или NginxНе сработал rewrite либо неверен document rootVirtualHost, server block, .htaccess, try_files
Страница ошибки в оформлении Yii2Запрос дошёл до приложения, но маршрут не найденurlManager, rules, контроллеры и действия
/index.php/site/index работает, а /site/index — нетPretty URL не передаётся в точку входаmod_rewrite или try_files
Не работает даже URL с index.phpНеверный корень сайта или обработка PHPdocument root, PHP-FPM, index.php

Начните с двух запросов:

curl -I https://example.test/index.php/site/index
curl -I https://example.test/site/index

Если первый URL открывается, а второй возвращает серверную 404, проблема находится перед Yii2. Если оба запроса доходят до Yii2, проверяйте маршруты приложения.

Проверьте enablePrettyUrl и showScriptName

'components' => [
    'urlManager' => [
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [],
    ],
],

enablePrettyUrl включает разбор красивых адресов, а showScriptName = false убирает index.php из генерируемых ссылок. Этот параметр не настраивает Apache или Nginx: запрос всё равно должен попасть в точку входа.

На время диагностики оставьте rules пустым и проверяйте стандартный маршрут /site/index. Так проще отличить ошибку rewrite от ошибки собственного правила.

Проверьте document root

В Yii2 Advanced публичным каталогом frontend-приложения должен быть frontend/web, а не корень проекта и не каталог frontend. Там находятся index.php, ресурсы и файл .htaccess.

/var/www/project/frontend/web/index.php

Для Basic Template публичным каталогом является web:

/var/www/project/web/index.php
Если document root указывает на frontend/web, правила rewrite должны применяться именно к этому каталогу. Файл в корне репозитория сервер может вообще не читать.

Apache: mod_rewrite и .htaccess

Проверьте модуль rewrite

apachectl -M | grep rewrite

В выводе должен присутствовать rewrite_module. После изменения модулей или VirtualHost перечитайте конфигурацию Apache.

Разрешите обработку .htaccess

При AllowOverride None Apache игнорирует правила из .htaccess. Для публичного каталога можно задать:

<Directory /var/www/project/frontend/web>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Затем проверьте конфигурацию:

apachectl configtest
systemctl reload apache2

Используйте минимальные правила

Файл frontend/web/.htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

Существующие файлы и каталоги отдаются напрямую, остальные запросы направляются в Yii2. Не добавляйте RewriteBase без необходимости: ошибочное значение часто ломает приложение в подпапке.

Сверьте VirtualHost

<VirtualHost *:80>
    ServerName example.test
    DocumentRoot /var/www/project/frontend/web
<Directory /var/www/project/frontend/web>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Проверьте, что домен обслуживает именно этот VirtualHost. Ошибка в ServerName, hosts или порядке виртуальных хостов может отправить запрос в конфигурацию по умолчанию.

Nginx: location и try_files

Nginx не читает .htaccess. Маршрутизация должна находиться в активном блоке server:

server {
    listen 80;
    server_name example.test;
    root /var/www/project/frontend/web;
    index index.php;
location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}
}

try_files сначала ищет реальный файл или каталог, затем передаёт запрос в index.php. $query_string сохраняет GET-параметры.

Частая ошибка — строка try_files $uri $uri/ =404;. Тогда несуществующий путь завершается серверной 404 и не попадает в Yii2. Ещё одна причина — правильный location / находится не в том блоке server, который обслуживает домен.

nginx -t
systemctl reload nginx

Если не открывается даже /index.php/site/index, проверьте сокет или адрес PHP-FPM, права доступа и значение SCRIPT_FILENAME.

Когда нужен baseUrl

baseUrl нужен, когда приложение опубликовано не в корне домена, а, например, по адресу https://example.test/app. При установке на отдельном домене Yii2 обычно определяет базовый путь автоматически.

'components' => [
    'request' => [
        'baseUrl' => '/app',
    ],
],

Значение должно совпадать с внешним URL-префиксом, а не с путём на диске. Нельзя указывать /var/www/project/frontend/web. Неверный baseUrl приводит к ошибочным ссылкам, ресурсам и редиректам, но не заменяет rewrite.

Для подпапки согласуйте внешний префикс, правило веб-сервера и request.baseUrl. При reverse proxy проверьте передачу префикса приложению.

Порядок диагностики

  1. Откройте /index.php/site/index. Если он не работает, исправьте document root и обработку PHP.
  2. Откройте существующий статический файл из frontend/web, чтобы подтвердить публичный каталог.
  3. Включите Pretty URL, отключите имя скрипта и временно уберите пользовательские правила.
  4. Проверьте /site/index. Серверная 404 указывает на Apache или Nginx, Yii-страница 404 — на маршрут.
  5. Для Apache проверьте модуль, AllowOverride, расположение .htaccess и активный VirtualHost.
  6. Для Nginx проверьте root, location /, try_files и активный блок server.
  7. После работы стандартного маршрута возвращайте собственные правила.
  8. Для установки в подпапке сверяйте внешний URL с baseUrl.

Кэш и перечитывание конфигурации

После правок Apache или Nginx должны перечитать конфигурацию. PHP-FPM обычно не перезапускают из-за rewrite, но это может понадобиться после правок пула или настроек PHP.

Чтобы исключить влияние кэша приложения, используйте штатную консольную команду проекта:

php yii cache/flush-all

Она выполняется из каталога с консольным файлом yii и требует настроенного консольного приложения. Также проверьте URL через curl или очистите кэш браузера, особенно после постоянных редиректов.

Кэш не исправляет неверный document root и не включает rewrite. Если 404 сформирована самим веб-сервером, очистка Yii-кэша не изменит результат.

Чек-лист

  • DocumentRoot или root указывает на frontend/web либо web.
  • URL с index.php открывает стандартный маршрут Yii2.
  • enablePrettyUrl включён, showScriptName отключён.
  • В Apache загружен mod_rewrite, разрешён .htaccess, правила лежат в публичном каталоге.
  • В Nginx используется try_files $uri $uri/ /index.php?$query_string;.
  • Домен обслуживается ожидаемым VirtualHost или блоком server.
  • Существующие файлы отдаются напрямую, остальные запросы попадают в index.php.
  • baseUrl задан только при реальном URL-префиксе.
  • После изменений конфигурация проверена, а веб-сервер перечитан.
  • Пользовательские правила возвращены после успешной проверки /site/index.