ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

一、多语言支持

  ThinkPHP 内置了对多语言的支持,如果应用项目涉及到国际化,那么可以定义相关的语言包文件以实现多语言支持。这里涉及的多语言支持是指模板语言,数据的多语言转换(翻译)不在这个范畴之内。

  1、配置

  在项目配置文件中做如下配置

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    ·自动侦测

    ThinkPHP 会自动判断当前用户的浏览器支持语言来定位该使用何种语言包,如果找不到相关的语言包文件,会使用默认语言。如果浏览器支持多种语言,那么取第一种支持语言!实际上,自动侦测是通过$_SERVER['HTTP_ACCEPT_LANGUAGE']来确定使用何种语言的

    ·手动设置

    除了自动侦测当前用户的浏览器语言之外,也可以在 URL 中指定使用何种语言。

    ·与多语言相关的文件包(系统)或目录(项目)

    ThinkPHP系统简体中文语言包:ThinkPHP系统目录/Lang/zh-cn.php

    ThinkPHP系统繁体中文语言包:ThinkPHP系统目录/Lang/zh-tw.php

    ThinkPHP系统美国英语语言包:ThinkPHP系统目录/Lang/en-us.php

    项目简体中文语言包目录:项目目录/Lang/<项目分组/>zh-cn/模块名(小写).php(或者各个模块公用的common.php)

    项目繁体中文语言包目录:项目目录/Lang/<项目分组/>zh-tw/模块名(小写).php(或者各个模块公用的common.php)

    项目美国英语中文语言包目录:项目目录/Lang/<项目分组/>en-us/模块名(小写).php(或者各个模块公用的common.php)

    如果有更多语言,可以依次创建更多的文件包和目录

  2、项目多语言实例

  下面举个栗子来看项目多语言支持的实例

    ·分别在项目目录->Lang目录->zh-cn目录->common.php文件、项目目录->Lang目录->zh-tw目录->common.php文件、项目目录->Lang目录->en-us目录->common.php文件中设定语言定义

      #简体中文

      ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】  

      #繁体中文

      ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

      #美式英语

      ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    ·在动作(比如Index模块的lang动作)中

    ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    ·在对应的模板(比如项目目录->Tpl目录->default目录->Index目录->lang.html文件)中

    ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    其实,这里不难看出,在模板中获取语言定义有两种方式!一是控制器分配过来(如{$message})、二是直接通过模板系统变量获取(如{$Think.lang.welcome})!稍微灵活一点,可以想到在模板中也可以通过{$Think.lang.message}获取语言定义的message的,实际上通过模板系统变量获取在底层也是通过L()方法实现的

*******************************我是一条分界线************************************************

1、其实说到这里,有必要研究一下L()函数

ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

注意批量定义和$_lang前面的static关键字

实际上,在入口文件中,关于多语言的操作过程如下

  根据浏览器支持的语言或默认语言或URL中传递过来的" l "值来将相应的系统语言定义和项目语言定义装载到{$Think.lang}和L()函数的$_lang变量中!装载到L()函数的$_lang变量中应该就是通过L()函数的批量定义功能来实现的,也就是说在入口文件中自动调用L()函数,并把相应的语言定义(系统和项目)数组传进去。$_lang前面的static关键字就保证了在入口文件(主栈)多次调用L()函数对$_lan*生的影响可以累加!至于怎么装载到{$Think.lang}中,ThinkPHP也应该是在入口文件中自动完成的,这个细节就不做讨论了

2、在动作中var_dump(L());可以验证上面的理解

ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

ps,L()函数在不传值时返回所有已装载的语言定义

  ·默认时(即为zh-cn时)

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  ·ch-tw时

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  ·en-us时

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  不难发现,zh-cn时不仅仅显示了刚才定义的项目语言定义,还显示了系统语言定义,而zh-tw和en-us却只显示了项目语言定义!原因很简单,系统语言定义目录(系统目录->lang目录)中并没有zh-tw.php和en-us.php语言文件

**********************************************************************************************

  3、定义项目模块语言包

  上面一个例子中,项目目录->Lang目录->语言目录中定义了一个common.php语言文件,该语言文件是该项目的各个模块都可以用的(即访问该项目的任意模块,common.php文件中的语言定义都会被装载到{$Think.lang}和L()函数中的$_lang中的),而ThinkPHP还支持单独为某一模块创建语言定义文件,此时语言定义文件名就是模块名,不过要小写。比如说为User模块创建的语言定义文件就是user.php,那么只有在访问该项目的User模块时,user.php文件中的语言定义才会被装载到{$Think.lang}和L()函数中的$_lang中

  不过要注意的是,如果模块语言文件与公共语言文件有相同的键时,则前者会覆盖后者该相同的键!从这个特性以及array_merge()函数的特性可以推测,对于公共语言文件和模块语言文件,应该是分开加载的,即调用了两次L()函数,且先加载公共语言文件,后加载模块语言文件!

  这里还提一点,如果在控制器中通过L($name,$value)来动态增加或者修改语言定义时,$name必须得为String,否则是加进去的,看L()源码即知!而且在语言包文件中,语言定义的数组键也要是String,虽然是int也可以加载进去,但是鉴于array_merge()函数的操作,最好也要是String

  4、模型中使用语言包

  项目多语言支持中除了模板模块动作要用到语言包之外,在模型类里也可能需要用到语言包(如自动验证的提示信息)。要在项目模型里使用语言包,只需将原来写入验证规则的提示信息修改一下。举个栗子

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  5、强调一下,不管是语言文件/目录的命名还是URL中'l'值,格式都要按照$_SERVER['HTTP_ACCEPT_LANGUAGE']来,即简体中午必须是zh-cn、繁体中文是zh-tw、美式英语是en-us、小鬼子语是jp、韩语是ko、德语是de、法语是fr

  6、针对系统多语言补充个栗子

    ·在系统目录->Lang目录中添加一个en-us.php文件,并写上如下语句

    ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    ·访问一个不存在的动作lang1,并在URL后加上/l/en-us

    ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

    ·访问一个不存在的动作lang1,默认情况(zh-cn)下是这样的

    ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  7、不难看出,ThinkPHP对于多语言支持具有自动侦测,自动加载的特点,能够很方便的实现系统项目上的多语言支持效果

二、多模板主题

  相比多语言,多模板主题要简单得多

  1、配置

  在项目配置文件中做如下配置

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  2、创建模板主题目录

  即在项目目录->Tpl目录中创建多个子目录,一个目录就是一套模板主题,如下

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  创建了三个子目录,即为三个模板主题,这三个目录中的模板一般内容都是一样的,只不过样式不一样

  3、在三个子目录的对应于User模块的Index动作的模板中,分别都加上如下语句测试

  ThinkPHP教程_PHP框架之ThinkPHP(十二)【多语言与多模板主题】

  ps,ThinkPHP针对模板主题还有个记录机制,就是会记录上一次关闭浏览器时的主题