htaccess虚拟语言文件夹URL重写:页面名称重复为URL文件夹问题
问题背景
我有一个包含3个页面的小型PHP网站,页面内容可根据URL中的语言动态翻译为荷兰语(nl)或英语(en),网站文件结构如下:
\index.php \page-one.php \page-two.php
期望实现的URL规则
https://www.example.com/ => 根据浏览器语言跳转至https://www.example.com/en/或nl/ https://www.example.com/en/ => \index.php https://www.example.com/en/page-one/ => \page-one.php https://www.example.com/en/page-two/ => \page-two.php https://www.example.com/nl/ => \index.php https://www.example.com/nl/page-one/ => \page-one.php https://www.example.com/nl/page-two/ => \page-two.php
本地WAMP环境的.htaccess规则(可正常运行)
RewriteEngine On RewriteBase / RewriteCond %{REQUEST_URI} !(/$|\.) RewriteRule (.*) %{REQUEST_URI}/ [R=301,L] RewriteCond %{HTTP:Accept-Language} ^nl RewriteCond %{THE_REQUEST} \ /+(?!(en|nl)/).* RewriteRule ^(.*)$ /nl/$1 [L,R] RewriteRule ^nl/(.*)$ /$1 [L] RewriteCond %{THE_REQUEST} \ /+(?!(en|nl)/).* RewriteRule ^(.*)$ /en/$1 [L,R] RewriteRule ^en/(.*)$ /$1 [L]
OVH虚拟主机上的问题
部署后出现以下异常:
- 正常:
https://www.example.com/跳转至https://www.example.com/en/或nl/ - 正常:
https://www.example.com/en/对应index.php - 异常:
https://www.example.com/en/page-one/打开的是index.php(而非page-one.php) - 异常:
https://www.example.com/en/page-two/打开的是index.php(而非page-two.php) - 仅重复页面名称的URL能访问对应页面:比如
https://www.example.com/en/page-one/page-one/可打开page-one.php - 错误URL也能访问对应页面:比如
https://www.example.com/en/page-one/page-two/可打开page-two.php
推测是.htaccess第10、14行的规则被执行了两次导致的问题。
解决方案
问题根源在于OVH主机的Apache配置可能开启了MultiViews选项,或者原规则的通用匹配逻辑导致内部重写被重复触发。修改后的.htaccess规则如下:
RewriteEngine On RewriteBase / # 强制URL以斜杠结尾(仅针对非文件请求) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} !/$ RewriteRule ^(.*)$ /$1/ [R=301,L] # 处理根路径的语言跳转 RewriteCond %{THE_REQUEST} ^GET\ /(?!en/|nl/).*$ RewriteCond %{HTTP:Accept-Language} ^nl [NC] RewriteRule ^$ /nl/ [R=301,L] RewriteCond %{THE_REQUEST} ^GET\ /(?!en/|nl/).*$ RewriteRule ^$ /en/ [R=301,L] # 内部重写:精确匹配每个页面的语言前缀URL RewriteRule ^(en|nl)/page-one/$ /page-one.php [L] RewriteRule ^(en|nl)/page-two/$ /page-two.php [L] RewriteRule ^(en|nl)/$ /index.php [L]
修改说明
- 优化斜杠结尾规则:增加
%{REQUEST_FILENAME} !-f条件,避免对实际存在的静态文件(如图片、CSS)强制添加斜杠。 - 精确控制根路径跳转:仅针对根路径
/执行语言跳转逻辑,避免干扰已带语言前缀的URL。 - 明确页面匹配规则:放弃原有的通用匹配逻辑,为每个页面编写精确的重写规则,彻底避免重复触发重写的问题。
这种写法逻辑清晰,适配OVH主机的配置特性,能确保每个URL都正确映射到对应的PHP文件。
内容的提问来源于stack exchange,提问作者Chris Aelbrecht
相关产品推荐
相关产品推荐

