欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

ThinkPHP3.1快速入门(17)多语言

shiping1 的头像
ThinkPHP支持多语言,采用的是语言文件的方式。如果你的应用涉及到多个语言版本和国际化的支持,那么可以定义相关的语言包文件。任何字符串形式的输出,都可以定义语言常量。

启用多语言

要启用多语言功能,首先要下载多语言行为扩展(http://www.thinkphp.cn/extend/186.html),或者下载官方的完整扩展包(http://www.thinkphp.cn/down/253.html)里面也已经包含多语言行为扩展了,把下载后解压到的CheckLangBehavior.class.php 文件放入ThinkPHP/Extend/Behavior(如果没有请手动创建)目录下面。然后在项目的行为配置文件(Conf/tags.php)中启用多语言行为,添加如下配置项:
  1. return array(
  2.     // 添加下面一行定义即可
  3.     'app_begin' => array('CheckLang')
  4.  );
复制代码
 
表示在app_begin标签位置执行多语言检测行为。
由于多语言默认是关闭的,我们还要在项目配置文件(Conf/config.php)中开启语言包功能:
  1. 'LANG_SWITCH_ON' => true,   // 开启语言包功能
复制代码
 
其他的多语言相关配置参数包括:
  1. 'LANG_AUTO_DETECT' => true, // 自动侦测语言 开启多语言功能后有效
  2.  'DEFAULT_LANG' => 'zh-cn', // 默认语言
  3.  'LANG_LIST'        => 'zh-cn,en-us', // 允许切换的语言列表 用逗号分隔
  4.  'VAR_LANGUAGE'     => 'l', // 默认语言切换变量
复制代码
 
如果开启了LANG_AUTO_DETECT,表示会自动侦测当前语言,否则就采用DEFAULT_LANG的语言设置。
语言包的使用由系统自动判断当前用户的浏览器支持语言来定位,如果浏览器支持多种语言,那么取第一种支持语言。
也可以在URL地址中使用参数来切换多语言,例如:
  1. http://localhost/Lang/index.php/?l=en-us
复制代码
 
多语言切换采用了Cookie机制,因此会记住当前的语言选择。
多语言的切换受LANG_LIST参数控制,如果浏览器自动侦测的语言或者用户切换的语言在LANG_LIST之外则无效,系统会采用默认语言。
例如,上面的设置参数情况下,访问:
  1. http://localhost/Lang/index.php/?l=zh-tw
复制代码
 
由于zh-tw语言未在多语言列表中,所以将会采用简体中文zh-cn语言包。

定义语言包

可以为项目定义不同的语言文件,语言文件包括系统语言包和项目语言包。框架的系统语言包目录在系统框架的Lang目录下面,每个语言都对应一个语言包文件,系统默认有简体中文语言包文件zh-cn.php和英文语言包en-us.php ,如果要增加繁体中文zh-tw或者其他语言包,只要对照系统已有的语言包增加相应的文件。

语言文件主要提供对模板的多语言支持,数据的多语言转换(翻译)不在这个范畴之内。ThinkPHP具备语言包定义、自动识别、动态定义语言参数的功能。并且可以自动识别用户浏览器的语言,从而选择相应的语言包(如果有定义)。
项目语言包文件位于项目的Lang目录下面,并且按照语言类别分子目录存放,在执行的时候系统会自动加载,无需手动加载。
语言子目录采用浏览器的语言命名(全部小写)定义,例如English (United States) 可以使用en-us作为目录名。一般情况下,如果项目不大,那定义common.php文件即可:
  1. Lang/zh-cn/common.php
复制代码
 
如果你的项目比较大,则可以按照模块或者分组来单独定义。具体的语言包文件命名规范如下:
项目公共语言包语言目录/common.php
项目分组语言包语言目录/分组名.php
项目模块语言包不存在分组情况:语言目录/模块名(小写).php
存在分组的情况:语言目录/分组名/模块名(小写).php
语言包文件可以按照模块来定义,每个模块单独定义语言包文件,文件名和模块名称相同,例如:
  1. Lang/zh-cn/user.php 表示给User模块定义简体中文语言包文件
  2.  Lang/zh-tw/user.php 表示给User模块定义繁体中文语言包文件
复制代码
 
分组的模块语言包定义受TMPL_FILE_DEPR参数配置影响,如果你修改了TMPL_FILE_DEPR参数,例如:
  1. 'TMPL_FILE_DEPR'=>'_',
复制代码
 
那么,分组的模块语言包定义方式应该改为:
  1. 语言目录/分组名_模块名(小写).php
复制代码
 
如果你采用了新版的独立分组模式的话,那么可以直接在分组的Lang目录下定义分组语言文件,
  1. Lang/分组名.php
复制代码
 
ThinkPHP语言文件定义采用返回数组方式:
  1. return array(
  2.     'lan_define'=>'欢迎使用ThinkPHP',
  3.  );
复制代码
 

使用语言定义

定义了语言文件后,我们通常需要改变控制器中的提示信息用法,例如:
  1. throw_exception'新增用户失败!');
复制代码
 
我们采用语言包后(例如在语言包里面增加了ADD_USER_ERROR 语言配置变量),在程序中的写法就要改为:
  1. throw_exceptionL('ADD_USER_ERROR'));
复制代码
 
也就是说,字符串信息要改成L方法和语言定义来表示。
如果ADD_USER_ERROR语言变量没有定义的话,L方法会输出当前的字符串ADD_USER_ERROR本身,所以你不用担心ADD_USER_ERROR是否有定义,可以在最后统一修改语言文件。
定义好语言文件后,也可以在程序里面动态设置语言定义的值,使用下面的方式:
  1. L('ADD_USER_ERROR','新增用户错误!');
  2. $value = L('ADD_USER_ERROR');
复制代码
 
模型类的自动验证功能里面会用到提示信息,这个部分也可以使用多语言的特性。例如:
原来的方式是把提示信息直接写在模型里面定义
  1. array('title','require','标题必须!',1),
复制代码
 
如果使用了语言文件的话(假设,我们在当前语言包里面定义了' lang_var'=>'标题必须!')
还可以这样定义模型的自动验证:
  1. array('title','require','{%lang_var}',1),
复制代码
 
如果要在模板中输出语言变量不需要在Action中赋值,可以直接使用模板引擎特殊标签来直接输出语言定义的值:
  1. {$Think.lang.lang_var}
复制代码
 
可以输出当前选择的语言包里面定义的 lang_var 语言定义。

来自 http://www.thinkphp.cn/info/188.html
 
评论(42相关
thinkphp传奇11月05日
一般高大上,国际化的网站才用得着多语言呀。
ywmprogrammer2014年10月15日
这个多语言没啥用,还是学习了
xinglongjian2014年09月29日
如何在javascript里应用多语言支持?
jspdba2014年08月16日
为什么设置default_lang=>'zh-cn',且auto_detect***=false时,不能切换语言?l=zh-tw
32215052014年05月16日
竟然有人困死了
红法师2014年03月24日
想要加载分组模块时候,注意大小写啊
marshalmackes2014年03月22日
今天发现一个问题,这里的多语言标记是在cookie里存在的,可能会导致搜索引擎只能收入默认语言页面。请官方留意。
tanmingjun2014年02月27日
非常好的文章,写的非常详细,按楼主的方法肯定可以实现(亲自实验过),有个地方特别需要注意,文件Lang/zh-cn/common.php(自定义的语言文件)是放在拟开发的那个应用(也就是项目,比如Home)里面的,不要放错了(我第一次尝试的时候就把它放到ThinkPHP框架里面的Lang文件夹里去了,结果很不乐观...呵呵)
25879463972014年01月10日
为什么我这里会出现定义的常量大写输出?
回复metaza2014年03月06日
在"App/conf/"下,创建tags.php文件,加入return array(
// 添加下面一行定义即可
'app_begin' => array('CheckLang')
);
qufo2014年01月07日
在 PHP 中写中文总感觉怪怪的。所有消息 都改语言了。
卧波长龙2013年11月29日
....
tree1002013年11月22日
困死啦。。。
jiewuzhe022013年11月16日
幸福曲线:兴趣-挫折-厌恶-理解-麻木
sara_org2013年11月15日
官方出demo!
yj2438939422013年10月09日
试了半天没出来,真纠结
gghhnn2013年09月30日
话说每一个超链接都要加这个语言检测变量 l 吗?
回复yj2438939422013年10月11日
您好,能够发一封关于thinkphp多语言的代码到我邮箱吗,地址是243893942@qq.com,小弟没看懂这个教程
回复tanmingjun2014年02月27日
不需要每个链接都带上语言检查参数(l),但传递的参数形式貌似必须是通过问号传参的方式(也就是类似的http://domain.com?l=en-us(这样是肯定可以的,但http://domain.com/l/en-us好像就不行了,这个还有待研究))
xxm2013年09月10日
交友回复 积分是干什么用的
lajitree2013年09月04日
我也有这个感觉。我也多回复的。
tp849137402013年09月03日
学习
回复yj2438939422013年10月11日
您好,能够发一封关于thinkphp多语言的代码到我邮箱吗,地址是243893942@qq.com,小弟没看懂这个教程
_freelin2013年08月23日
找到Thinkphp/Extend/Behavior/ChecklangBehavior.class.php做如下修改:
  1.         
  2.         $langSet = C('DEFAULT_LANG');
  3.         // 启用了语言包功能
  4.         // 根据是否启用自动侦测设置获取语言选择
  5.         //if (C('LANG_AUTO_DETECT')){      注释掉
  6.             if(isset($_GET[C('VAR_LANGUAGE')])){
  7.                 $langSet = $_GET[C('VAR_LANGUAGE')];// url中设置了语言变量
  8.                 cookie('think_language',$langSet,3600);
  9.             }elseif(cookie('think_language')){// 获取上次用户的选择
  10.                 $langSet = cookie('think_language');
  11.             }elseif(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){// 自动侦测浏览器语言
  12.                 preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
  13.                 $langSet = $matches[1];
  14.                 cookie('think_language',$langSet,3600);
  15.             }
  16.             if(false === stripos(C('LANG_LIST'),$langSet)) { // 非法语言参数
  17.                 $langSet = C('DEFAULT_LANG');
  18.             }
  19.        // }  这个也注释掉
  20.  
复制代码
 
复制代码
 
复制代码
 
复制代码
 

之后就可以了
phantomshop2013年08月17日
{$Think.lang.lang_var}
各变量代表什么呢 我都显示不出来
回复kang_web2013年09月23日
{$Think.lang.lang_var}是指语言包里的lang_var对应的内容,例如
  1. <?php
  2.  return array(
  3.     'site_home'    =>    '网站首页',
  4.  );
  5.  ?>
复制代码
 
复制代码
 
复制代码
 
,我要在页面中显示《网站首页》的时候就是
  1. {$Think.lang.site_home}
复制代码
 
复制代码
 
复制代码
 
,site_home就相当于lang_var,{$Think.lang}是tp获取系统语言变量的方式
http://doc.thinkphp.cn/manual/system_var.html 
http://doc.thinkphp.cn/manual/multi_lang.html
741886920@qq.com2013年08月15日
不明白到的怎么切换语言
YangHaiQuan2013年08月08日
小弟有个疑问。用了页面框架。。。分 header 和main 设置选择语言在header里面 选择过后也刷新的是header .而main里面没反应。。。要刷新下才行。。。请问该怎样处理嘞???
九日晴2013年08月07日
不错噢~~~~
回复yj2438939422013年10月11日
您好,能够发一封关于thinkphp多语言的代码到我邮箱吗,地址是243893942@qq.com,小弟没看懂这个教程
xiaoshuo2013年08月02日
成功了,但中间遇到了一点障碍。系统语言包是zh-cn.php和en-us.php两个文件,没有仔细看教程,就照搬到项目中发现不成功。回头看教程才知道项目中语言包是用zh-cn和en-us两个文件夹进行区分的。
mc-zone2013年07月31日
默认切换变量l怎么使用?
开启之后,设置 'LANG_LIST'=> 'zh-cn,en-us', 'VAR_LANGUAGE'=> 'l',
使用 index.php?l=en-us ,切换并不成功。只有在配置里把默认设为en-us才能切换到英文。语言包在系统包里都有。url模式也没问题。请问怎么使用才能自主切换?
回复kang_web2013年09月17日
要自主切换就不能用
  1. 'VAR_LANGUAGE' => 'l'
复制代码
 
复制代码
 
复制代码
 
,VAR_LANGUAGE是在没有开启自动侦测语言的情况下用的,开启后只能用DEFAULT_LANG来设置默认语言
  1. 'DEFAULT_LANG' => 'zh-cn',
复制代码
 
复制代码
 
复制代码
 
回复kang_web2013年09月23日
用DEFAULT_LANG来设置默认语言,不要用VAR_LANGUAGE,你的切换没问题
myfirtyou2013年07月30日
实然觉得我的积分好少 加油回复
xianglingchuan2013年06月14日
测试成功了,感觉还可以,以前没做过多语版的
guisz2013年03月26日
我在项目的Lang目录下建了zh-cn/common.php 定义了自己的语言数组,也在config.php配置了开启多语言,并在框架中加了多语言的支持。但是在 代码中用 echo L('_LAN_TEST_'); 却翻译不出来。我怀疑是语言文件没有加载,请高手指点一下。
回复りんきん2013年06月06日
li/behavior 那边文件也写吗
闲庭信步2013年03月15日
'LANG_AUTO_DETECT' => true, // 自动侦测语言 设置成false后,语言切换失效,是什么原因?
笑熬浆糊2013年02月21日
试不出来,不知道是什么原因。
kcy0032013年01月26日
数据库显示在页面怎样切换成英文
phpMax2013年01月16日
在配置文件中设置:'DEFAULT_LANG' => 'zh_cn'后,框架底层语言包文件,就没有加载了,这肿么办?
aayjaa2013年01月10日
'VAR_LANGUAGE' => 'l', // 默认语言切换变量 
请问这个是什么意思?
回复aayjaa2013年01月10日
知道了。- -~
jecken2013年01月05日
多语言、多模板怎么做?比如:英文版对应英文版的模板风格,中文版对应中文版的模板风格
回复邦备2013年12月05日
亲,这个问题你解决了没?
信达软件2012年12月17日
原生php模板如何输出{$Think.lang.lang_var}变量?
回复thinkphp2012年12月27日
直接用 echo L('lang_var'); 即可
gcq9112012年12月10日
文档中没有写独立分组的语言目录结构,建议添加。分析源码得出的结果,分模块的语言文件的结构是:Modules/分组名/Lang/语言包名/分组名/模块名(小写).php,例如,admin分组下的content模块语言包是:Modules/Admin/Lang/zh-cn/Admin/content.php
gcq9112012年12月10日
独立分组的情况,分模块的语言文件的结构是:Modules/分组名/Lang/语言报名/分组名/模块名(小写).php
3044294042012年12月07日
怎么没有人回答呢
wgbzxq2012年12月06日
请问下独立分组下的语言设置不成功,请写详细点谢谢
如果你采用了新版的独立分组模式的话,那么可以直接在分组的Lang目录下定义分组语言文件,
Lang/分组名.php
回复qiaoyinqian2012年12月15日
连个例子也没有,半天也使不出来。
3044294042012年12月05日
在独立分组下无法正常加载语言包?? 上面文档写得不是很清楚 要是我在独立分组下分模块配置语言包 目录结构怎样实现
小树叶子2012年12月02日
你好,在实践当中,我觉得还有改进的余地,例如繁体是有zh-tw/zh-hk之分,英语有 en-us/en-au 等等很多中分法,但如果只用一种统一的英语,例如就是 en 目录,那么 en-us/en-au是无法匹配的,我建议可以搞个参数,如果浏览器是:en-us或其他的,能自动调用 en 或指定的 语言包。
回复sangeng2012年12月02日
你可以自己判断IP来选语言
回复麦当苗儿2012年12月03日
你也可以写一个行为扩展,判断后 定义cookies 这样系统就会自动读取cookies 来加载语言包了

普通分类: