Использование Apache mod_rewrite для перенаправления на статический контент, если существует - PullRequest
1 голос
/ 02 марта 2012

Фон

Я оптимизирую некоторые страницы с высокой посещаемостью, создав статический кеш.Поскольку содержимое меняется не часто, механизм генерации и аннулирования кэша был простым.Однако в настоящее время я обращаюсь к кешу через PHP (базовая проверка file_exists()).Я хотел бы довести это до уровня веб-сервера, чтобы полностью исключить PHP.

Spec

У меня будет тысячи кэшированных страниц.Итак, дерево каталогов, которое я представляю, выглядит так:

year -> first id of digit -> second id of digit -> id.html

Я делю его таким образом, чтобы избежать десятков тысяч файлов в одном каталоге - насколько я понимаю, это снижение производительности.Я знаком с mod_rewrite, но не совсем уверен, как собрать необходимые фрагменты URL и определить, существует ли файл.

Вот пример входящего URL:

/2011/37823/some_slug

Некоторый псевдокод, используя приведенный выше URL:

RewriteCond %{REQUEST_URL} ^(\d{4})/...
RewriteCond /cache/$1/$3/$4/$2.html -f
RewriteRule - /cache/$1/$3/$4/$2.html [L]

Вопросы

  • Как я могу создать RewriteRule для вышеупомянутого?
  • Есть лилучший способ сделать это (используя технологии стека LAMP)?

Ответы [ 2 ]

1 голос
/ 02 марта 2012

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

RewriteCond %{DOCUMENT_ROOT}/cache/$1$2$3\.html -f
RewriteRule ^(\d+)(/\d+)(/[^/]+)$ /cache/$1$2$3.html [L]

Если вы хотите немного больше вложенности (папки, основанные на первой и второй цифрах идентификаторов, но игнорирующие остальную часть средней части URL), тогда это будет:

RewriteCond %{DOCUMENT_ROOT}/cache/$1$2/$3$4\.html -f
RewriteRule ^(\d+)(/\d)(\d)\d*(/[^/]+)$ /cache/$1$2/$3$4.html [L]

Сначала проверяется RewriteRule, чтобы увидеть, применяется ли правило.RewriteCond затем проверяет, существует ли файл (DOCUMENT_ROOT - корень сайта), используя записи из RewriteRule.Если это существует, то условия выполняются, и RewriteRule перезаписывает URL, обслуживая кэшированную страницу перед тем, как прекратить попытки перезаписи [L].

С точки зрения лучших параметров, это лучше, чем у PHPтак как он не запустит PHP для кэшированных страниц.Однако он будет проверять шаблон для каждого запроса ресурса.

0 голосов
/ 03 марта 2012

Это, я думаю, должно работать для вас:

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(\d{4})\/((\d)(\d)\d+)
RewriteCond %{DOCUMENT_ROOT}/cache/%1/%3/%4/%2.html -f
RewriteRule ^.* /cache/%1/%3/%4/%2.html [L,QSA]

Первое условие соответствует / (ГОД) / ((цифра1) (цифра2) цифра3-к-n).Парантезы говорят системе хранить значения внутри переменных% 1-% 4.Пожалуйста, обратите внимание на сложную часть, где есть парантезы внутри парантезов.Похоже, что регулярное выражение подсчитывает порядок из начала / открытия paranthese, поэтому внешний ( вокруг идентификатора будет% 2, а затем digit1 -% 3 и т. Д.

Второе условие проверяет полный файлдорожка.DOCUMENT_ROOT дает вам путь к локальной файловой системе.Обратите внимание, что я использую %, а не $.Это потому, что я использую сохраненные переменные из предыдущей строки, а не текущей.

RewriteRule просто переписывает все на ваш новый путь.[L] сообщает apache, чтобы он прекратил поиск переписываний, а [QSA] (Query String Append) возвращает строку запроса после перезаписи (не уверен, что вам это нужно).

...