如何通过Apache重写隐藏URL语言标识并保留$_GET中的lang参数?
解决方案说明
首先明确:无法实现地址栏显示https://example.com/dev/的同时,$_GET数组中存在lang=en——因为$_GET的参数完全来自URL的查询字符串,地址栏没有查询参数的话,$_GET里就不会对应存在该参数。但可以实现地址栏保持干净,同时服务器能识别当前语言(通过Cookie或Session),以下是具体实现方案:
实现思路
通过Apache Rewrite规则配合Cookie,先捕获用户访问的语言标识,存入Cookie后重定向到干净的URL;后续访问时,从Cookie中读取语言标识,传递给PHP(可选择写入$_GET或直接读取Cookie)。
Apache Rewrite配置(.htaccess)
RewriteEngine On # 1. 捕获/dev/{lang}请求,设置语言Cookie后重定向到干净的/dev/ RewriteCond %{QUERY_STRING} !^lang= RewriteRule ^dev/(\w+)$ /dev/? [R=302,L,CO=lang:$1:example.com:7200:/:false:true] # 2. 可选:将Cookie中的语言标识写入$_GET(若需直接用$_GET['lang']) RewriteCond %{HTTP_COOKIE} lang=(\w+) RewriteRule ^dev/$ dev?lang=%1 [L]
规则解释
- 第一条规则:当用户访问
https://example.com/dev/en时,先检查查询字符串中没有lang=(避免循环重定向),然后设置一个名为lang的Cookie(值为捕获到的en,有效期2小时,作用域为example.com),最后外部重定向到https://example.com/dev/(末尾的?用于清除查询字符串,保证地址栏干净)。 - 第二条规则:当用户访问干净的
/dev/时,若Cookie中存在lang参数,内部重写为dev?lang=xx,这样PHP的$_GET['lang']就能获取到语言标识;若不需要依赖$_GET,可直接在PHP中读取Cookie,这条规则可以省略。
PHP代码处理
如果选择直接读取Cookie(无需第二条Rewrite规则),PHP中可以这样处理:
// 获取语言标识,默认设为中文(可根据需求修改) $lang = isset($_COOKIE['lang']) ? $_COOKIE['lang'] : 'zh-CN'; // 后续业务逻辑使用$lang变量即可
如果使用了第二条Rewrite规则,也可以直接通过$_GET['lang']获取:
$lang = isset($_GET['lang']) ? $_GET['lang'] : 'zh-CN';
补充说明
如果坚持要让$_GET['lang']存在且地址栏无参数,这违背HTTP协议的设计(GET参数必须体现在URL中),因此无法实现,只能通过Cookie、Session这类客户端存储来保存语言标识,同时保持地址栏简洁。
内容的提问来源于stack exchange,提问作者Ivan Vetoshkin
相关产品推荐
相关产品推荐

