简体   繁体   English

.htaccess - 如何将 URL 重定向到文件夹,然后重定向到 PHP 文件

[英].htaccess - How to redirect URL to a folder and then to a PHP file

I am setting up a cache system for my blog (not a WordPress) and I want to store the cached files in a posts/ folder, so I don't fill my root folder with post files.我正在为我的博客(不是 WordPress)设置缓存系统,并且我想将缓存的文件存储在posts/文件夹中,因此我不会用帖子文件填充我的根文件夹。

I have a file called post.php that creates these posts files if the slug corresponds to an actual post in a different website (I check this with WordPress REST API).我有一个名为post.php文件,如果 slug 对应于不同网站中的实际帖子,它会创建这些帖子文件(我使用 WordPress REST API 进行了检查)。 So when I visit mywebsite.com/slug-to-post and this URL doesn't match any of my files on the root level, it fallbacks to post.php using FallbackResource post.php in .htaccess , and post.php uses this slug to create a cached version and stores it, but since there can be thousands of posts, I don't want the files to be stored in the root level, but in posts/name-of-the-file .因此,当我访问mywebsite.com/slug-to-post并且此 URL 与我在根级别上的任何文件都不匹配时,它post.php使用.htaccess FallbackResource post.php ,而post.php使用此slug 创建缓存版本并存储它,但由于可能有数千个帖子,我不希望将文件存储在根级别,而是在posts/name-of-the-file

So that file would be accessed via mywebsite.com/posts/slug-to-post but for SEO purposes I still want it to be mywebsite.com/slug-to-post .因此可以通过mywebsite.com/posts/slug-to-post访问该文件,但出于 SEO 的目的,我仍然希望它是mywebsite.com/slug-to-post What should I write in my .htaccess to fallback any unknown file to the posts/ folder, and if the file doesn't exists there, fallback again to post.php , which is stored on root level?我应该在我的 .htaccess 中写入什么以将任何未知文件回post.php posts/文件夹,如果该文件不存在,则再次回post.php存储在根级别的post.php

Nothing I've tried has worked so far.到目前为止,我尝试过的一切都没有奏效。 To cache the files I'm using the code present here: https://phppot.com/php/php-cache-for-dynamic-web-pages/要缓存文件,我使用这里的代码: https : //phppot.com/php/php-cache-for-dynamic-web-pages/

UPDATE: This is my current .htaccess file:更新:这是我当前的.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]

You are requesting a file of the form /<post-slug> , which either:您正在请求格式为/<post-slug> ,它可以:

  1. Maps to a file of the form /<post-slug>.php in the document root.映射到文档根目录中形式为/<post-slug>.php的文件。

  2. OR, maps to a cached version of this file of the form /posts/<post-slug>.php .或者,映射到此文件的缓存版本,格式为/posts/<post-slug>.php

  3. Otherwise, the request should fallback to /post.php in the document root.否则,请求应该回/post.php文档根目录中的/post.php

Try something like the following (using mod_rewrite) in addition to your FallbackResource directive:除了您的FallbackResource指令外,请尝试以下操作(使用 mod_rewrite):

# 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

This does assume that your <post-slug> does not contain dots ( . ).这确实假设您的<post-slug>不包含点 ( . )。 This makes it easier to avoid conflicts with static resource or create an unnecessary filesystem check after rewriting the request to <post-slug>.php .这使得在将请求重写为<post-slug>.php更容易避免与静态资源的冲突或创建不必要的文件系统检查。 If the <post-slug> can contain dots then we'll need to alter the RewriteRule pattern and add an additional condition .如果<post-slug>可以包含点,那么我们需要改变RewriteRule模式并添加一个额外的条件

NB: MultiViews needs to be disabled for this to work properly (it may already be disabled on your server).注意:需要禁用 MultiViews 才能正常工作(它可能已经在您的服务器上被禁用)。


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

Just a few notes on your original rule block.只需对原始规则块做一些说明。

  • If you make the RewriteRule pattern more restrictive, rather than matching anything (ie. .* ) then you can probably avoid the condition that checks that the request does not map to a filesystem directory.如果您使RewriteRule模式更具限制性,而不是匹配任何内容(即 . .* ),那么您可能可以避免检查请求未映射到文件系统目录的条件。 (Is a request for a filesystem directory ever a valid request?) (对文件系统目录的请求是否是有效的请求?)

  • A literal dot in the RewriteCond TestString (1st argument) does not need to be backslash escaped. RewriteCond TestString (第一个参数)中的文字点不需要反斜杠转义。 This is an "ordinary" string, not a regex.这是一个“普通”字符串,而不是正则表达式。

  • Note that %{REQUEST_FILENAME}.php is not necessarily the same as the (potentially) rewritten URL $1.php - it will depend on the request and the filesystem (since REQUEST_FILENAME is calculated after the request has been mapped to the filesystem), but since you are allowing anything (ie. .* ) then there is potential for error here.请注意, %{REQUEST_FILENAME}.php不一定与(可能)重写的 URL $1.php - 它取决于请求和文件系统(因为REQUEST_FILENAME请求映射到文件系统计算的),但是由于您允许任何内容(即 . .* ),因此这里可能会出错。

  • The NC flag is superfluous, since the RewriteRule pattern is not case-sensitive anyway. NC标志是多余的,因为RewriteRule模式无论如何都不区分大小写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM