2015-12-01 2 views
2

Я заметил проблему с [OR] в htaccess, которую я не понимаю. То, что я хочу сделать, - перенаправить каждый несуществующий файл и каждый файл, который является .php-файлом (а не /index.php) на/404 /. По моему разумению следующие два блока должны делать то же самое:проблема htaccess - странное поведение [OR]

# .htaccess 1 
RewriteEngine on 

# cond 1 
RewriteCond %{REQUEST_FILENAME} !-f [OR] 
# cond 2 
RewriteCond %{REQUEST_FILENAME} !index\.php$ 
# cond 3 
RewriteCond %{REQUEST_URI} \.php$ 
# rule 1 
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L] 

# rule 2 
RewriteRule ^(([^/\.]+)/?)*?$ /index.php [L] 

и это:

# .htaccess 2 
RewriteEngine on 

# cond 1 
RewriteCond %{REQUEST_FILENAME} !-f 
# rule 1 
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L] 

# cond 2 
RewriteCond %{REQUEST_FILENAME} !index\.php$ 
# cond 3 
RewriteCond %{REQUEST_URI} \.php$ 
# rule 2 
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L] 

# rule 3 
RewriteRule ^(([^/\.]+)/?)*?$ /index.php [L] 

Тем не менее, только второй блок делает то, что я хочу. Например, первый .htaccess - не перенаправляет несуществующий файл a.pdf и вместо этого отображает сообщение сервера по умолчанию о том, что файл не найден.

Может кто-нибудь, пожалуйста, объясните мне это?

+0

Для любого URL-адреса с несуществующим файлом и, например: '/ a.pdf' – eithed

+0

В этом проблема - по моему мнению, оба этих блока должны делать то же самое. Поведение, однако, верно во втором блоке – eithed

+0

Пожалуйста, создайте файл index.php с «A» в нем. Используйте первый .htaccess. Для URL '/ a.pdf' вы получите ответ сервера« Не найден »по умолчанию. Используйте второй .htaccess. Вы получите «A», так как '/ a.pdf' разрешит'/404/', который будет разрешен к'/index.php'. Теперь - почему поведение не одно и то же? – eithed

ответ

2

Ваш OR условный в первом .htaccess находится в неправильном порядке.

[OR] флаг создает группу вокруг двух утверждений, эффективно писать ваши условно как:

if (
    (FILE_NOT_FOUND or FILE_NAME === 'index.php') 
    and REQUEST_URI ends in .php 
) { ... } 

Написанная в таком порядке, условное никогда не будет совпадать с URI, который заканчивается расширением другой чем PHP ,

То, что вы на самом деле хотите это:

if (
    (FILE_NOT_FOUND or REQUEST_URI ends in .php) 
    and FILE_NAME !== 'index.php' 
) { ... } 

который может быть выражен просто переставлять два связанных условия перезаписи:

RewriteCond %{REQUEST_FILENAME} !-f [OR] 
RewriteCond %{REQUEST_FILENAME} \.php$ 
RewriteCond %{REQUEST_URI} !index\.php 
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L] 

Вы можете даже поймать свою ошибку, читая ваши собственные слова (упрощенный чтобы показать фактическое условное значение, которое вы имели в виду):

Что я хочу сделать, это перенаправить каждый несуществующий файл [или] каждый .php файл, [и] нет /index.php to/404 /.

Here is a good StackOverflow question/answer о приоритете [OR] в .htaccess файлы, если вы хотите узнать больше о том, как на самом деле работает mod_rewrite внутри.

+0

Большое спасибо - я уже рассматривал этот ответ, но, наверное, это было поздно, или я устал, и приоритет [OR] не зарегистрировался должным образом в моем мозгу (и, глядя на него со стандартного языковой приоритет точки зрения Я был в убытке от того, что происходит). – eithed

Смежные вопросы