В первых двух правилах есть логический недостаток в том, что существует файл php или html.Проверка URI также фактически является дубликатом шаблона правила перезаписи, а! F подразумевает! -D.Вы также можете сложить их в одно правило:
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC]
Последние два в порядке, но я бы поменял порядок, если запросы html встречаются чаще, чем php
Почему MultiViews не делаетt help
Options +MultiViews
реализует концепцию, известную как согласование содержимого , и при этом Apache вызывает подзапрос для анализа корневого имени файла.Он сканирует каталог на наличие известных комбинаций filename.extension, поэтому в этом случае, если существует xxx.php
, а ваш запрос на xxx
, он заменит xxx.php и сделаетвнутреннее перенаправление, которое затем вызывает срабатывание вашего первого правила, удаляя расширение .php , и это вызывает ошибку, которую вы видите.
Итак, (i) вам нужно отключить множественные просмотры и (ii) подзапросы;(iii) обнаружение и предотвращение повторных петель.Это одно решение, которое будет делать то, что вы хотите:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /foo
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]