我想使用 mod_rewrite(在 .htaccess 中)将“干净”的 URL 映射到子目录中相应的 php 文件,例如:
https://example.com/test/
-->
https://example.com/p/test.php
我的第一步是向所有缺少斜杠的网址添加尾部斜杠:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*[^/])$ $1/ [L,R=301]
然后我添加了以下几行以确保路径/文件尚不存在:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
最后是RewriteRule
,它将请求的路径映射到子目录/p/
中的相应文件:
RewriteRule ^(.+)$ /p/$1\.php
这似乎工作正常,除非我请求的 URL 不存在。那么该操作就会导致死循环如:
https://example.com/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/p/test/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/.php/
我已经尝试在 RewriteRule
之前添加另一个 RewriteCond
,以确保请求的文件确实存在于子文件夹 /p/
中,但我的方法不起作用:
RewriteCond %{DOCUMENT_ROOT}/p/$1.php -f
谁能告诉我我做错了什么?
最佳答案
I’ve already tried adding another
RewriteCond
right before theRewriteRule
to ensure the requested file actually exists in the subfolder/p/
, but my approach doesn’t work:
是的,您需要这样做...检查您打算重写的文件是否确实存在,而不是重写任何根本不存在的文件(如果目标也不存在,这将导致重写循环)存在)。但是,您的“问题”是您的网址以尾部斜杠结尾,并且您似乎没有在规则中考虑到这一点。因此,给出 /test/
的请求您正在有效地尝试测试 %{DOCUMENT_ROOT}/p/test/.php
,自然不存在。
您需要排除RewriteRule
中捕获子模式中的尾部斜杠。 模式。例如:
# Rewrite "/test/" to "/p/test.php" if it exists
RewriteCond %{DOCUMENT_ROOT}/p/$1.php -f
RewriteRule ^(.+)/$ p/$1.php [L]
不需要额外的文件系统检查(和开销)来检查请求是否映射到文件或目录 - 因为这些应该是互斥的事件。 (如果您确实有一个同名目录,则相应的 .php
文件将无法访问。)
您的完整文件将变为:
RewriteEngine on
# Append trailing slash (if omitted)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ /$1/ [R=301,L]
# Rewrite "/test/" to "/p/test.php" if it exists
RewriteCond %{DOCUMENT_ROOT}/p/$1.php -f
RewriteRule ^(.+)/$ p/$1.php [L]
请注意,规则中不需要附加尾部斜杠的第二个条件来测试请求的 URL 是否不以尾部斜杠结尾,因为这已由 RewriteRule
处理。 模式(如果有尾部斜杠,模式将根本不匹配)。
并且不需要 RewriteBase
指令在这里。在外部重定向上,最好是明确的,并在替换字符串中包含斜杠前缀。
旁白:
My first step was to add trailing slashes to all URLs that lack one:
需要澄清的是,您的所有内部链接必须已更新以包含尾部斜杠,否则您的用户(和搜索引擎)将一直被不必要地重定向。
关于php - mod_rewrite到子目录中相应的php文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77771812/