Mod Rewrite игнорируя -d

Через день или два я все еще борюсь с Mod Rewrite. Кажется, что 60% моего времени разработки уходит на борьбу с сервером.

Моя текущая структура URL такова, что все http://example.com/xyz и http://example.com/xyz/abc должен обрабатываться index.php. Проблема в том, что у меня есть раздел http://example.com/admin/, который представляет собой настоящий каталог, к которому мне нужно получить доступ через HTTP-запрос (это каталог CMS)

Когда я пытаюсь перейти на CMS http://example.com/admin/, мой URL меняется на http://example.com/admin/?n=admin и возвращает ошибку 404. , Мой index.php получает n=admin в качестве аргумента.

Я не могу понять, почему эти два условия игнорируются:

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^admin(?:\/)?$

И почему я получаю это перенаправление на http://example.com/admin/?n=admin (вместо того, чтобы просто остановиться на http://example.com/admin/.

Options +FollowSymlinks
RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^admin(?:\/)?$

# allow access to certain subdirectories.
RewriteRule ^admin(?:\/)?$ /admin/ [L,NC]

# redirect all old URLs to new pages (or 404 sitemap page if no analog?).
RewriteRule ^company/about(?:\/)?$ /company [R=301,L,NC]

# catch any others and try to serve them right
RewriteRule ^/?(.+).html$ /$1 [R=301,L]

RewriteRule ^/?([0-9]+)(?:\/)?$ /index.php?p=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$1 [L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)/([-a-zA-Z0-9_+]+)(?:\/)?$ /index.php?n=$2 [L]

Может ли кто-нибудь предложить какие-либо идеи или указать на какие-либо недостатки в .htaccess?


person Antony Carthy    schedule 19.11.2009    source источник
comment
Подводя итог моему вопросу, я не могу получить доступ к каталогу, который существует на сервере, потому что переписывание мода перенаправляет меня. Этого не должно происходить, потому что я установил RewriteCond %{REQUEST_FILENAME} !-d   -  person Antony Carthy    schedule 19.11.2009
comment
Вопрос, чтобы попробовать, измените предпоследнее или последнее правило с ...php?n=... на ...php?m=..., чтобы увидеть, какие правила действительно применяются. Также как вы говорите, что он перенаправляется на admin/?n=admin, но вы ссылаетесь на index.php, получая параметр n=admin   -  person Simeon Pilgrim    schedule 19.11.2009


Ответы (2)


Каждый RewriteCond применяет только следующий RewriteRule.

поэтому только ваше первое правило имеет условие.

Ваши варианты - повторить правила или сделать их окончательными и выходными (не могу вспомнить флаг для этого из моей головы)

person Simeon Pilgrim    schedule 19.11.2009
comment
Это предполагает, что это сработает: RewriteCond %{REQUEST_FILENAME} -f RewriteCond %{REQUEST_FILENAME} -d RewriteCond %{REQUEST_FILENAME} ^admin(?:\/)?$ RewriteRule ^(.?)$ $1 [L] Но это не? - person Antony Carthy; 19.11.2009
comment
На самом деле это должно работать, но не работает: RewriteCond %{REQUEST_FILENAME} -f [ИЛИ] RewriteCond %{REQUEST_FILENAME} -d [ИЛИ] RewriteCond %{REQUEST_FILENAME} ^admin(?:\/)?$ RewriteRule ^( .?)$ $1 [л] - person Antony Carthy; 19.11.2009
comment
Я все еще очень уверен, что ваше первое правило никогда не будет совпадать, так как вы его обусловливаете, если путь не является файлом, и путь не является каталогом, и путь не является admin/ или admin, тогда, если путь admin/ или admin перепишите его в /admin/ Таким образом, никаких чистых изменений из-за предыдущего нет. - person Simeon Pilgrim; 19.11.2009

Попробуйте это правило перед другими вашими правилами:

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

Это завершит процесс перезаписи, если запрошенный путь может быть сопоставлен с существующим каталогом. То же самое относится и к использованию -f вместо этого.

person Gumbo    schedule 19.11.2009