Я настраиваю систему кэширования для своего блога (не 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-кэш-для-динамических-веб-страниц/
Обновлено: Это мой текущий .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]
Да, slug-to-post
— это имя кэшированного файла, поэтому оно будет выглядеть примерно так: root dir/posts/slug-to-post.php
«Ничто из того, что я пробовал, пока не сработало». - было бы полезно посмотреть, что вы уже пробовали. Иногда может потребоваться только небольшое изменение существующих директив, или это может указывать на конфликт с существующими директивами, если директивы выглядят нормально (что является распространенной проблемой).
Это мой текущий .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]
Как я уже упоминал в вашем ответе, теперь mywebsite.com/post-slug.php
работает, но mywebsite.com/post-slug
выдает ответ 404.
Вы запрашиваете файл формы /<post-slug>
, который либо:
Сопоставляется с файлом формы /<post-slug>.php
в корне документа.
ИЛИ сопоставляется с кэшированной версией этого файла в форме /posts/<post-slug>.php
.
В противном случае запрос должен вернуться к /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
шаблон и добавить дополнительный условие.
NB: MultiViews необходимо отключить, чтобы это работало должным образом (возможно, оно уже отключено на вашем сервере).
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php [NC,L]
Всего несколько заметок о вашем исходном блоке правил.
Если вы сделаете RewriteRule
шаблон более ограничительным, а не совпадающим с что-нибудь (т.е. .*
), то вы, вероятно, сможете избежать условия, которое проверяет, что запрос не отображается в каталог файловой системы. (Является ли запрос каталога файловой системы допустимым?)
Буквальную точку в RewriteCond
тестовая строка (1-й аргумент) не нужно экранировать обратной косой чертой. Это "обычная" строка, а не регулярное выражение.
Обратите внимание, что %{REQUEST_FILENAME}.php
не обязательно совпадает с (потенциально) переписанным URL-адресом $1.php
- это будет зависеть от запроса и файловой системы (поскольку REQUEST_FILENAME
вычисляется после, запрос был сопоставлен с файловой системой), но поскольку вы разрешаете что-либо (т.е. .*
), то здесь возможна ошибка.
Флаг NC
лишний, так как RewriteRule
шаблон в любом случае не чувствителен к регистру.
Привет! Спасибо за ваш ответ. Теперь проблема: допустим, в моей папке post-slug.php
есть файл posts
, путь к которому: mywebsite.com/posts/post-slug.php
. Теперь, с новым .htaccess
, если я перехожу к mywebsite.com/post-slug
, я получаю ответ 404, но если я перехожу к mywebsite.com/post-slug.php
, это работает. Поэтому мне нужно добавить .php к 1 доллару, что-то вроде RewriteCond %{DOCUMENT_ROOT}/posts/$1.php -f
Как я могу это сделать? Заранее спасибо!
Ах, хорошо, это имеет больше смысла. :) Ваши URL-адреса не имеют расширения ... пользователь запрашивает /post-slug
(на самом деле они никогда не запрашивают /post-slug.php
напрямую), но это сопоставляется с /post-slug.php
внутренне. Я переписал свой ответ. (Нужно ли вам обрабатывать ситуацию, если пользователь должен запросить /post-slug.php
напрямую? Например, были ли эти .php
URL-адреса проиндексированы поисковыми системами или на них ссылаются третьи лица?)
Привет! Извините за мой поздний ответ! Мне удалось заставить его работать с вашим последним ответом, большое спасибо!
Как
slug-to-post
сопоставляется с файлом? Это имя файла?