кажется, что при доступе к site.com/api/v1/ не выполняется api_v1.php. Вместо этого он продолжит и выполнит index.php
Да, потому что первое правило переписывает запрос на api_v1.php и это в конечном итоге переписывается на index.php по второму правилу (потому что php нет в списке исключенных расширений в первом условие, второе условие также выполняется успешно, поэтому третье условие не обрабатывается (см. ниже) во время второго прохода механизма перезаписи. В каталог контекст (т. .htaccess) л флаг не останавливает всю обработку, он просто останавливает текущий проход через механизм перезаписи. Механизм перезаписи работает до тех пор, пока URL-адрес не пройдет без изменений.
Вы можете решить эту проблему на Apache 2.4, используя КОНЕЦ флаг вместо л, по первому правилу остановить всю обработку переписывающим движком.
Например:
RewriteRule ^api/v1/api_v1.php [NC,END]
(я удалил конец (.*)$ на регулярном выражении, поскольку здесь это не обязательно и делает регулярное выражение незначительно менее эффективным.)
Однако тот факт, что запрос на существующую .php файл переписан вашими более поздними правилами, действительно демонстрирует, что ваши вторые и третьи правила, похоже, не работают должным образом...
№ 2. Перепишите в index.php, за исключением существующих файлов design/document/favicon/robots
RewriteCond %{REQUEST_URI} !.(css|js|png|jpg|jpeg|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$
RewriteCond %{REQUEST_URI} !^(robots\.txt|favicon\.ico)$ [ИЛИ]
RewriteCond %{REQUEST_FILENAME} !-f
Правило перезаписи ^(.*)$ index.php [L]
№3. Перепишите все остальное
Правило перезаписи ^(.*)$ index.php [L]
Если вы запрашиваете что-то.php затем первый условие успешно (потому что .php является нет включены в список). Второе условие также выполнено (это не robots.txt или же favicon.ico). Поскольку второе условие явно объединяется с третьим условием, третье условие не обрабатывается.Все условия соблюдены и запрос переписан на index.php (несмотря на погоду что-то.php есть или нет).
Если, с другой стороны, вы просите ресурс.css затем первый условие терпит неудачу (потому что он имеет .css расширение). Поскольку это условие неявно объединяется по И, дальнейшие условия не обрабатываются и правило не срабатывает. Затем третье правило безоговорочно переписывает ресурс.css к index.php, независимо от того, существует он или нет!
Таким образом, это не проверяет, что запрошенный ресурс (css, jpgи т. д.) «существует», как следует из предыдущего комментария. Третье условие (которое проверяет, что запрос не отображается в файл) обрабатывается только в том случае, если предыдущее условие ИЛИ не выполняется И первое условие успешно. Другими словами, третье условие обрабатывается только тогда, когда вы запрашиваете /роботы.txt - что, я уверен, не входит в ваши намерения.
Другими словами, правила № 2 и № 3 (несмотря на их кажущуюся сложность), похоже, в значительной степени переписываются. все к index.php.
Комплексное решение
На основании ваших дополнительных комментариев:
Для подмножества типов файлов обслуживайте ресурс, если он существует. Если ресурс не существует, отправьте запрос на index.php.
Для других типов файлов отправьте запрос на index.php, независимо от того, существует этот ресурс или нет.
Несколько запросов (т. /роботы.txt и /favicon.ico) не следует отправлять index.php.
Вместо этого попробуйте следующее:
# Предотвратить перенаправление 301 с косой чертой, когда папка существует и к ней не добавлена косая черта
# Это не проблема безопасности, так как используется PHP-маршрутизатор и все пути перенаправляются
Слэш-каталог выключен
# Поскольку установлено "DirectorySlash Off", убедитесь, что списки каталогов mod_auotindex отключены
Параметры - Индексы
RewriteEngine включен
№1. Переписать URL API
RewriteRule ^api/v1/api_v1.php [NC,END]
№ 2. Известные URL/файлы обслуживаются напрямую
RewriteRule ^(index\.php|robots\.txt|favicon\.ico)$ - [КОНЕЦ]
№3.Определенные типы файлов (ресурсы) обслуживаются напрямую, если они существуют
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.(css|js|png|jpe?g|bmp|gif|ttf|eot|svg|woff|woff2|ico|webp|pdf)$ - [КОНЕЦ]
№ 4. Перепишите все остальное
RewriteRule ^ index.php [КОНЕЦ]
Правила заканчиваются раньше для всего, что нужно обслуживать напрямую, поэтому нам нужно только переписать index.php один раз в последнем правиле.
Обратите внимание, что я включил index.php в правиле №2. Это оптимизация, хотя она и не является строго необходимой при использовании КОНЕЦ флаг (в отличие от л) по последнему правилу.
При желании вы можете выбрать перенаправление любого непосредственный просьбы к index.php вернуться к корню (для канонизации URL для поисковых систем). Это на всякий случай /index.php раскрывается (или угадывается) конечному пользователю.
Например, добавьте следующее после первого правила для API:
#1.5 Перенаправление прямых запросов к "/index.php" обратно в "/" (корневой)
Условия перезаписи %{ENV:REDIRECT_STATUS} ^$
Правило перезаписи ^index\.php$ / [R=301,L]
условие который проверяет против REDIRECT_STATUS переменная среды необходима для предотвращения цикла перенаправления — чтобы избежать перенаправления переписанного URL-адреса. (Хотя, опять же, это не является строго обязательным при использовании КОНЕЦ флаг на последнем/переписывающем правиле.)