3.2.3 - 严重 - 未处理
现在有这种需求,通过数据库设置,配置前后台使用不同的语言。但是目前好像TP还不能实现,或者是我没有找到实现的方法。我特别注意了下,官方检测多语言的行为,如果开启了多语言,但是没有开启自动侦测,那么他会直接调用配置文件里面的默认语言。
而如果同时开启了多语言和自动侦测,那么以下的代码:
// 根据是否启用自动侦测设置获取语言选择
if (C('LANG_AUTO_DETECT',null,true)){
if(isset($_GET[$varLang])){
$langSet = $_GET[$varLang];// url中设置了语言变量
cookie('think_language',$langSet,3600);
}elseif(cookie('think_language')){// 获取上次用户的选择
$langSet = cookie('think_language');
}elseif(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){// 自动侦测浏览器语言
preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$langSet = $matches[1];
cookie('think_language',$langSet,3600);
}
if(false === stripos($langList,$langSet)) { // 非法语言参数
$langSet = C('DEFAULT_LANG');
}
}
主要检测3个方面,1.URL中是否有设置多语言的参数,如果有,直接使用,并将该使用语言记入名字为think_language的cookie中
2.判断是否存在名字为think_language的cookie,如果存在,直接使用
3.侦测浏览器语言
4.最后如果以上都不匹配,使用配置中的默认语言
我的多语言配置存储在数据库中,通过获取数据库内容,在公用继承类中调用修改名字为think_language的cookie,实现了多语言的后台配置。
但是,这个配置会对前后台同时生效!
如果,我不开启自动侦测,通过C方法动态修改默认语言是否能够达到我的效果的,后来发现,语言检测的行为发生在控制器方法之前,修改也不能达到我要的效果,我想到以下2种解决方案:
1)修改语言检测行为的标签位,比如控制器方法之后,但是没有这个标签,我猜测有也不行,因为语言文件必须要在控制器方法之前加载才行。例如我尝试了=》view_begin 视图输出开始标签位。模板输出是达到要求了,但是控制器内部的文本没有修改。PASS
2)找到这个检测多语言行为,扩展该标签,或者找到多语言检测行为之前的标签扩展。我测试了下,确实是可以的。例如:
'app_begin' => array('Home\Behaviors\TestBehavior','Behavior\CheckLangBehavior'),
TestBehavior中,通过获取数据库的默认语言修改,前后端语言配置。建议:
如果语言检测行为能够增加一个判断,即在将语言项写入 cookie时候判断,判断用户当前访问的模块,然后根据不同模块设置不同的cookie如,think_home_language,think_admin_language, 则作为开发人员,可以轻易通过数据库配置,修改不同模块的语言项而无需扩展行为标签。
---------------
考虑到后端的语言项一旦确定,极少会修改,我采取了以下折衷方案:
。
通用conf中,多语言自动检测开启,后台CONF中关闭多语言自动侦测,这样一来,后台的语言就可以直接在conf配置文件中修改,而无需考虑cookie的think_language是使用的什么语言了。