mod_rewrite 删除 .php 扩展名并保留 GET 参数
Posted
技术标签:
【中文标题】mod_rewrite 删除 .php 扩展名并保留 GET 参数【英文标题】:mod_rewrite to remove .php extension AND preserve GET parameters 【发布时间】:2013-04-20 06:32:40 【问题描述】:我已经查看了这些解决方案,但它们都没有真正在我身上正常工作:
mod_rewrite to remove .php but still serve the .php file?
How to remove file extension from website address?
How to use Apache Mod_rewrite to remove php extension, while preserving the GET parameters?
他们只是不做以下事情,这是我需要做的:
1) 从文件中删除 .php 扩展名,而不是 /index.php 显示 /index
2) 保留 GET 参数(我在加载文件时读取并存储在会话 cookie 中,在标题中),因此 /index.php?a=1&b=2 可能显示 /index/a1/b2
3) 在子域和 https:// 上工作,而不会完全弄乱 URL 或以无限循环或其他方式结束...
有没有人知道如何将这些规则组合在一起,以便正确涵盖以上 3 点?
这是我作为起点的工作:
RewriteCond %THE_REQUEST (\.php(.*)\sHTTP/1)
RewriteRule ^(.+)\.php$ /$1 [R=301,L,QSA]
【问题讨论】:
在此处发布您的 .htaccess 内容 更新了我的起点 .htaccess 你写的代码有什么问题? 【参考方案1】:你看错了。您不想将对 .php 文件的请求重定向到一个干净的地址,因为您从不希望用户首先看到 .php。相反,您需要接受一个不以 .php 结尾的请求,然后检查文件(在表面之下)是否实际上具有 .php 扩展名。然后,如果是这种情况,静默重写请求以添加 .php 扩展名,这样用户就不需要看到扩展名了。
尝试以下方法:
RewriteCond %DOCUMENT_ROOT/$1.php -f
RewriteRule ^([a-zA-Z0-9_-]+)/?$ /$1.php [QSA]
一旦将“.php”添加到请求的末尾,RewriteCond 就会检查请求(附加到 DOCUMENT_ROOT 路径的末尾)是否形成有效的文件名。如果是这样,则允许 RewriteRule 静默重写请求,以便将“.php”添加到请求路径中。 QSA 标志告诉 mod_rewrite 将现有查询字符串附加到新请求路径的末尾,因此应保留您的 GET 变量。
请注意,DOCUMENT_ROOT 可能已经或可能没有尾部斜杠,因此您可能需要在 RewriteCond 中删除 $1
之前的斜杠。
对于查询字符串参数,mod_rewrite 无法处理无限数量的变量,因此您需要在问题中给出明确的请求模式,然后 mod_rewrite 解决方案才能提供将其映射到查询字符串的方法。
【讨论】:
【参考方案2】:通过httpd.conf
启用mod_rewrite和.htaccess,然后把这段代码放到你.htaccess
的DOCUMENT_ROOT
目录下:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
## hide .php extension
# To externally redirect /dir/foo.php to /dir/foo
RewriteCond %THE_REQUEST ^[A-Z]3,\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=302,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_FILENAME.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
一旦您确认它工作正常,然后将R=302
更改为R=301
。 (在测试你的 mod_rewrite 规则时避免使用R=301
(永久)。
【讨论】:
我原以为这会导致无限循环。 THE_REQUEST 是否通过静默重写保持不变? @Arkanon:是的,THE_REQUEST remain unchanged
是正确的。 THE_REQUEST 表示 Apache Web 服务器从浏览器接收到的原始未更改的请求行。
方便的提示。我必须记住这一点。
我找到的最佳解决方案。 +1
嗨 Anubhava,这是迄今为止最好的解决方案!有一个问题,如何获取 .php 之后的参数?例如。 domain.com/file.php/name1/name2 如何获取 domain.com/file/name1/name2 ?我正在更改引用您的第二点的扩展名。【参考方案3】:
尝试以下方法:
RewriteCond %THE_REQUEST "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]
【讨论】:
以上是关于mod_rewrite 删除 .php 扩展名并保留 GET 参数的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 mod_rewrite 的情况下运行没有扩展的 PHP?
使用 mod_rewrite RewriteRule 重写所有查询以不需要 .php 扩展名