.htaccess - Как перенаправить URL в папку, а затем в файл PHP - PullRequest
2 голосов
/ 30 мая 2019

Я настраиваю систему кэширования для своего блога (не WordPress) и хочу сохранить кэшированные файлы в папке posts/, поэтому я не заполняю свою корневую папку файлами сообщений.

У меня есть файл с именем post.php, который создает эти файлы сообщений, если слаг соответствует фактическому сообщению на другом веб-сайте (я проверяю это с помощью WordPress REST API). Поэтому, когда я захожу на mywebsite.com/slug-to-post и этот URL не соответствует ни одному из моих файлов на корневом уровне, он возвращается к post.php с использованием FallbackResource post.php в .htaccess, а post.php использует этот слаг для создания кэшированной версии и хранит его, но поскольку может быть тысячи сообщений, я не хочу, чтобы файлы сохранялись на корневом уровне, а в posts/name-of-the-file.

Так что этот файл будет доступен через mywebsite.com/posts/slug-to-post, но для целей SEO я все еще хочу, чтобы он был mywebsite.com/slug-to-post. Что я должен написать в моем .htaccess для восстановления любого неизвестного файла в папке posts/, и если файл там не существует, снова вернуться к post.php, который хранится на корневом уровне?

Ничто из того, что я пробовал, до сих пор не сработало. Для кеширования файлов я использую код, представленный здесь: https://phppot.com/php/php-cache-for-dynamic-web-pages/

ОБНОВЛЕНИЕ: Это мой текущий .htaccess файл:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/posts/$1 -f
RewriteRule ^([^/]+\.php)$ /posts/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^/]+\.php$ post.php [L]

1 Ответ

0 голосов
/ 05 июня 2019

ОБНОВЛЕНИЕ: Вы запрашиваете файл вида /<post-slug>, который либо:

  1. Отображение в файл вида /<post-slug>.php в корне документа.

  2. ИЛИ сопоставляется с кэшированной версией этого файла в форме /posts/<post-slug>.php.

  3. В противном случае запрос должен вернуться к /post.php в корне документа.

Попробуйте что-то вроде следующего (используя mod_rewrite) в дополнение к вашей директиве FallbackResource:

# Disable MultiViews
Options -MultiViews

RewriteEngine On

# 1. Check for file in the document root
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/.]+)$ /$1.php [L]

# 2. Check for cached version in the "/posts" subdirectory
RewriteCond %{DOCUMENT_ROOT}/posts/$1.php -f
RewriteRule ^([^/.]+)$ /posts/$1.php [L]

# 3. Request does not map to a file, so fallback to "/post.php"
FallbackResource /post.php

Предполагается, что ваш <post-slug> не содержит точек (.). Это позволяет избежать конфликтов со статическим ресурсом или создать ненужную проверку файловой системы после переписывания запроса в <post-slug>.php. Если <post-slug> может содержать точки, тогда нам нужно изменить шаблон RewriteRule и добавить дополнительное условие .

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


RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [NC,L]

Всего несколько заметок о вашем исходном блоке правил.

  • Если вы сделаете шаблон RewriteRule более ограничительным, чем сопоставление что-либо (то есть. .*), то вы, вероятно, можете избежать условия, которое проверяет, что запрос не сопоставляется с каталогом файловой системы. (Является ли запрос на каталог файловой системы когда-либо действительным запросом?)

  • Буквенную точку в RewriteCond TestString (1-й аргумент) не нужно экранировать обратной косой чертой. Это «обычная» строка, а не регулярное выражение.

  • Обратите внимание, что %{REQUEST_FILENAME}.php не обязательно совпадает с (потенциально) перезаписанным URL $1.php - это будет зависеть от запроса и файловой системы (поскольку REQUEST_FILENAME вычисляется после запрос был сопоставлен с файловой системой), но поскольку вы разрешаете что-либо (т. е. .*), то здесь есть вероятность ошибки.

  • Флаг NC является излишним, поскольку шаблон RewriteRule в любом случае не учитывает регистр.

...