我最近开始使用重写引擎,并请求帮助删除 PHP 扩展并在 URL 中添加尾部斜杠。 anubhava here提供了一个完美的解决方案。为了快速参考,下面提供了配置文件:
.htaccess
RewriteEngine On
# removes .php and adds a trailing /
# i.e. to externally redirect /path/file.php to /path/file/
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=307,NE,L]
# adds a trailing slash to non files
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule [^/]$ %{REQUEST_URI}/ [L,R=307,NE]
# internally rewrites /path/file/ to /path/file.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)/$ $1.php [L]
此配置适用于以下 URL:
https://example.com/test.php
https://example.com/test
https://example.com/test/
以上网址全部改写为:
https://example.com/test/
到目前为止一切都很好,除了如果 PHP 文件包含查询字符串,它的工作方式与我想要的有点不同。例如,如果 URL 是:
https://example.com/test.php?lang=en&id=3
然后重写为:
https://example.com/test/?lang=en&id=3
不幸的是,我没有预料到这个问题,这给我带来了问题,因为我无法捕获下面的 PHP 文件中的查询字符串。
测试.php
<?php
session_start();
if(isset($_GET['lang']))
{
$_SESSION['lang'] = $_GET['lang'];
}
?>
为了解决这个问题,我需要一种方法来捕获 PHP 查询字符串。我认为将 URL 重写为
https://example.com/test?lang=en&id=3/
可以。不过,我对替代解决方案持开放态度。编辑:鉴于问题的复杂性,尾部斜杠是可选的,但我想删除 PHP 扩展并能够捕获查询字符串。
RewriteRule 指令允许使用 QSA 标志,将查询字符串复制到重写的 URL。
当替换 URI 包含查询字符串时,RewriteRule 的默认行为是丢弃现有查询字符串,并将其替换为新生成的查询字符串。使用 [QSA] 标志会导致查询字符串被组合。
所以你的
[L]
标志应该类似于 [L,QSA]
。
有关其他文档,您可以找到 RewriteRule 指令的可用标志列表。
我通过阅读无脂肪框架
.htaccess
示例发现了这一点。
RewriteEngine On
RewriteRule ^(app|dict|ns|tmp)\/|\.ini$ - [R=404]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA] <------------------------------------ HERE
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
考虑到我们在评论中的讨论,这(尽管仅在有缺陷的在线 htaccess 测试器上进行了非常粗略的测试)应该可行。
注意到我删除了“/”的添加,除非有一个真实的目录。添加 / 对于 URL 具有重要意义(它指的是目录,而不是文件!),因此仅仅为了美观而添加它是没有意义的,这正是一切变得复杂并出错的原因。
如果您使用路由(例如在 Laravel 或其他平台中),当然您可以对 url 进行任何您想要的操作,但由于您似乎不需要,并且似乎需要与服务器上的文件匹配的 URL,你只是真的不想添加随机斜杠。
RewriteEngine On
# removes .php externally
# i.e. to externally redirect /path/file.php to /path/file
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=307,NE,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]