Перенаправить в резервный файл, если первая попытка не удалась - PullRequest
2 голосов
/ 11 февраля 2012

У меня есть это в моем .htaccess:

RewriteRule ^images/([^/\.]+)/(.+)$ themes/current/images/$1/$2 [NC]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^images/([^/\.]+)/(.+)$ modules/$1/images/$2 [L,NC]

Идея заключается в следующем:

// Rewrite this...
images/calendar/gear.png

// ... to this
themes/current/images/calendar/gear.png

// HOWEVER, if that rewritten path doesn't exist, rewrite the original URL to this:
modules/calendar/images/gear.png

Здесь изменяются только calendar и gear.png, первое из которых может быть любым другим отдельным словом, а второе - именем файла (возможно, с путем) к файлу изображения.

Я могу переписать исходный URL-адрес первым, как показано в примере, просто отлично, но я не могу сделать, чтобы мой .htaccess обслуживал файл из другого, запасного местоположения, если первое местоположение 404s. У меня сложилось впечатление, что не использование [L] в моем первом RewriteRule перезапишет URL для RewriteCond.

Проблема, с которой я столкнулся, заключается в том, что вместо предоставления резервного файла браузер просто отображает 404 для первого переписанного пути (themes/current/calendar/gear.png), вместо возврата к modules/calendar/gear.png. Что я делаю не так?

Обратите внимание, что мое регулярное выражение не идеально, но я могу уточнить это позже. Прямо сейчас я интересуюсь самой логикой переписывания.

1 Ответ

1 голос
/ 12 февраля 2012

Правила Fallthrough чреваты ошибками.Моя общая рекомендация заключается в том, что любое правило со строкой замены, отличной от -, должно вызывать внутреннее перенаправление для перезапуска анализа .htaccess.Это позволяет избежать ошибок подзапроса и URI_PATH.

Далее, когда вы перейдете на 404, опять же, по моему опыту, это невозможно исправить.У меня есть фрагмент, который делает нечто похожее на то, что вы пытаетесь сделать:

# For HTML cacheable blog URIs (a GET to a specific list, with no query params, 
# guest user and the HTML cache file exists) then use it instead of executing PHP

RewriteCond %{HTTP_COOKIE} !blog_user
RewriteCond %{REQUEST_METHOD}%{QUERY_STRING}  =GET               [NC]
RewriteCond %{ENV:DOCUMENT_ROOT_REAL}/blog/html_cache/$1.html -f
RewriteRule ^(article-\d+|index|sitemap.xml|search-\w+|rss-[0-9a-z]*)$ \
            blog/html_cache/$1.html                              [L,E=END:1]

Обратите внимание, что я делаю условный тест в пространстве файловой системы, а не в пространстве URI (Местоположение).Так что в вашем случае это отобразится на

RewriteCond %{DOCUMENT_ROOT}/themes/current/images/$1/$2l -f
RewriteRule ^images/(.+?)/(.+)$ themes/current/images/$1/$2 [L]

Хотя выполните phpinfo (), чтобы проверить, использует ли ваш хостинг-провайдер альтернативу DOCUMENT_ROOT , если это предложение общего хостинга, напримеральтернативная переменная окружения, как моя, использует DOCUMENT_ROOT_REAL .

Второе правило будет обнаружено при второй обработке, прошедшей после внутреннего перенаправления.

...