php - mod_rewrite到子目录中相应的php文件

标签 php apache .htaccess mod-rewrite

我想使用 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 the RewriteRule 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/

相关文章:

python - Flask 和 WSGI 出现间歇性 500 HTTP 错误

PHP Paypal 集成测试帐号

php - htaccess 图片 url 重写规则

php - 使 CMS 模板在普通网站上工作需要什么

java - Apache Tomcat 是Web服务器还是应用服务器

php - 条件目录索引

apache - Nginx 对 cms 后端的重写规则

php - 如何通过php调用api并从中获取json文件

php - fatal error 在 null 上调用成员函数 prepare()

php - 在 php 中使用 @ 而不是 isset