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

问题描述 投票:0回答:1

我想使用 mod_rewrite (在 .htaccess 中)将“干净”的 URL 映射到子目录中相应的 php 文件,例如:

https://example.com/test/
-->
https://example.com/p/test.php

我的第一步是向所有缺少斜杠的 URL 添加尾部斜杠:

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/

我已经尝试在

RewriteCond
之前添加另一个
RewriteRule
,以确保请求的文件确实存在于子文件夹
/p/
中,但我的方法不起作用:

RewriteCond %{DOCUMENT_ROOT}/p/$1.php -f

谁能告诉我我做错了什么?

php apache .htaccess mod-rewrite
1个回答
0
投票

我已经尝试在

RewriteCond
之前添加另一个
RewriteRule
,以确保请求的文件确实存在于子文件夹
/p/
中,但我的方法不起作用:

是的,您需要这样做...检查您打算重写的文件是否确实存在,而不是重写任何不存在的文件。但是,您的“问题”是您的网址以尾部斜杠结尾,并且您似乎没有在规则中考虑到这一点。因此,如果请求

/test/
,您实际上是在尝试测试
%{DOCUMENT_ROOT}/p/test/.php
,而它自然不存在。

您需要排除

RewriteRule
pattern 中捕获子模式中的尾部斜杠。例如:

# 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
pattern 处理(该模式只是如果尾部有斜杠,则不匹配)。

© www.soinside.com 2019 - 2024. All rights reserved.