通常人们写程序时都是将文字写死在程序里的,比如:echo "Hello World!"; ,假如要改成它国语言,写国际化程序,就要逐个打开进行修改,程序较短时还行,若程序有上万甚至更多,改起来就不是那么容易了。近来随着i18n的逐渐标准化,我也来讲一讲在PHP中如何实现国际化支持。跟其他程序语言一样,在 PHP 也可以利用 gettext套件写作 i18n 程序,实现 NLS(Native Language Support) 国际化支持。
实现流程:程序设计者在程序码中写入所要显示的信息,在运行程序时并不会直接显示程序设计师所写的信息,而会先去找一个所设置语系的信息档。如果未找到,才会去显示程式码中的信息。
一、安装设置gettext 套件:
windows系统:
1、打开php.ini档,查找extension=php_gettext.dll,去掉前面的“;”
2、保存,然后restart server。
若一切顺利,就可以在 phpinfo() 中看到 gettext 字样,至此已设置完毕。
二、php_gettext.dll套件里有好几个函式,具体请看相关的manual。在这里我们只用记住3个函式就行了,如下:
string bindtextdomain ( string domain, string directory)
string textdomain ( string text_domain)
string gettext ( string message)
2,php-gettext的使用.以一个具体的例子说明
如果debian系列的linux用户,注意查看本地语言支持。 vim /usr/share/i18n/SUPPORTED
中文:zh_CN.UTF-8
英文:en_US.UTF-8
德文:de_DE.UTF-8
法文:fr_FR.UTF-8
如果没有,则相应的安装之。方法:sudo apt-get locale-gen zh_CN.UTF-8
在php程序中,可以使用gettext()来标记需要翻译的语言包,gettext()函数常用_()代替;
2.1 建立文件目录
mkdir gettext
cd gettext
touch Locale.php
touch test.php
//中文mo文件的地方.
mkdir -p Locale/zh_CN/LC_MESSAGES
//英文文mo文件的地方.
mkdir -p Locale/en_US/LC_MESSAGES
至于编辑工具,由于 po 文件本身就是一个文本文件,所以任何文本编辑器都可以使用。除了专门编辑 po 文件的poEdit ,还推荐使用 poEdit 、EditPlus 、UltraEdit 或者你喜欢的 vi 或 vim 。
汉化mo文件需要的工具叫gettext,去http://gnuwin32.sourceforge.net/packages/gettext.htm 下载一个回来安装,然后运行:
msgunfmt.exe d:\english.mo -o d:\english.po
对english.po进行编辑、翻译,完成后再运行:
msgfmt.exe -o d:\chinese.mo d:\english.po
然后就编译完成了chinese.mo文件。
AccountSections.php
_('Could not retrieve the requested section please try again.');
mo文件中对应:
#: AccountSections.php:187
msgid "Could not retrieve the requested section please try again." //对应页面调用的key
msgstr "不能取回要求的类别, 请重试" //显示文字
2.2 Locale.php文件代码
- <?php
- /**
- * Dh_Locale 语言包类
- *
- * 系统语言包采用的是php-gettext模块.
- * 如果模板使用的是smarty.使用了smarty-gettext插件.插件地址http://sourceforge.net/projects/smarty-gettext/
- * php-gettext的安装和使用(ubuntu平台下)
- * 1 Installation of gettext package: sudo apt-get install php-gettext
- * 2 Install locales: see all locales in the file vim /usr/share/i18n/SUPPORTED
- * 3 设置文件目录结构;如: Locale/zh_CN/LC_MESSAGES 或者 Locale/en_US/LC_MESSAGES
- * 4 如果是smarty模板(使用{t}你好{/t}标记)。生成.c格式的文件;如:php -q tsmarty2c.php $file > text.c
- * 5 生成.po格式的文件;xgettext -o Dh.po --join-existing --omit-header --no-location text.c
- * 6 生成.mo格式的文件;msgfmt Dh.po -o Dh.mo
- * 7 移动mo文件到相应的Locale/en_US/LC_MESSAGES文件夹下面
- *
- * @package
- * @version $id$
- * @copyright 1997-2005 The PHP Group
- * @author erhuok <erhu.ok@gmail.com>
- * @license PHP Version 3.0 {@link http://www.php.net/license/3_0.txt}
- */
- class Dh_Locale {
- /**
- * _options 设置语言包的选项
- *
- * $this->_options['lang'] 应用程序使用什么语言包.php-gettext支持的所有语言都可以.
- * 在ubuntu下使用sudo vim /usr/share/i18n/SUPPORTED 主要是utf8编码
- * $this->_options['domain'] 生成的.mo文件的名字.一般是应用程序名
- *
- * @var array
- * @access protected
- */
- protected $_options;
- /**
- * __construct 构造函数 对象初始化时设置语言包的参数
- *
- * @access public
- * @return void
- */
- public function __construct($lang=null) {
- switch ( $lang ) {
- case 'cn':
- $this->_options = array('lang' => 'zh_CN.utf8','domain'=>'Dh');
- break;
- case 'en':
- case 'us':
- case 'eu':
- $this->_options = array('lang' => 'en_US.utf8','domain'=>'Dh');
- break;
- case 'de':
- $this->_options = array('lang' => 'de_DE.utf8','domain'=>'Dh');
- break;
- case 'fr':
- $this->_options = array('lang' => 'fr_FR.utf8','domain'=>'Dh');
- default:
- $this->_options = array('lang' => 'zh_CN.utf8','domain'=>'Dh');
- break;
- }
- $this->setApplicationLocale();
- }
- /**
- * setOptions 设置应用程序语言包的参数 放在在数组$this->_options中
- *
- * @param mixed $options
- * @access public
- * @return void
- */
- public function setOptions($options) {
- if(!empty($options)) {
- foreach ($options as $key => $option) {
- $this->_options[$key] = $option;
- }
- }
- }
- /**
- * setApplicationLocale 设置应用程序语言包
- *
- * @access public
- * @return void
- */
- public function setApplicationLocale() {
- putenv('LANG='.$this->_options['lang']);
- setlocale(LC_ALL,$this->_options['lang']);
- bindtextdomain($this->_options['domain'],dirname(__FILE__).'/Locale/');
- textdomain($this->_options['domain']);
- bind_textdomain_codeset($this->_options['domain'],'UTF-8');
- }
- }
- ?>
2.3 测试用例
- <?php
- require_once dirname(__FILE__).'/Locale.php';
- //cn or en
- $Lang = 'cn';
- $Locale = new Dh_Locale($Lang);
- $Checkout['AddressFields'] = array
- (
- 'Email' => array
- (
- 'Type' => 'text',
- 'Label' => _('邮箱'),
- 'Title' => _('请填写邮箱'),
- 'Class' => 'required',
- 'Filter' => 'string',
- ),
- 'PostCode' => array
- (
- 'Type' => 'text',
- 'Label' => _('邮政编码'),
- 'Title' => _('请填写邮政编码'),
- 'Class' => 'required',
- 'Filter' => 'int',
- ),
- );
- echo '<pre>';print_r($Checkout);echo '</pre>';
- ?>