php+gettext多多语言的探讨
五 18th
Web程序中使用php-gettext做多语言的探讨
一直在开发LAP电子商城系统,很多国内客户做外贸生意,不仅需要中英文,还通常要翻译成德文;研究了下php-gettext做多语言方案。写出来和大家分享下。
1,php-gettext的安装
1.1 gettext扩展在php5.2默认是开启的。
1.2 如果没开启,windows用户印象中是在php.ini开启php_gettext.dll扩展。
1.3 ubuntu系统中安装扩展很方便。sudo apt-get install php-gettext
1.4 如果服务器(如centos)是自己编译安装的。如果编译的时候没有–with-gettext.需要phpize编译安装gettext
进入php源码包,如 cd /usr/local/src/php/ext/gettext
phpize //运行后此目录下多出了一些configure文件
make
make install
按提示。将生成的gettext.so文件写入到php.ini中。如 extension=gettext.so;
重启 /etc/init.d/apache restart
2,php-gettext的使用.以一个具体的例子说明
中文: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
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文件夹下面
<code>
*
* @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′);
}
}
?>
</code>
2.3 测试用例
<code>
<?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>’;
?>
</code>
如果是smarty模板,需要使用smarty-gettext插件.使用{t}你好{/t}标记.如 <a href=”http://sourceforge.net/projects/smarty-gettext/”>{t}点击下载插件{/t}</a>
2.4 生成PO文件
如果是PHP文件 xgettext –from-code UTF-8 -o Dh.po –join-existing test.php
如果是smarty模板,在smarty-gettext插件中,有个tsmarty2c.php文件.
cd gettext
生成c文件
php -q tsmarty2c.php test.tpl > test.c
在生成po文件
xgettext –from-code UTF-8 -o Dh.po –join-existing test.c
2.5 生成mo文件
msgfmt -o Dh.mo Dh.po
将mo文件移动到Locale/en_US/LC_MESSAGES下
2.6 调试:localhost/test.php
3. 后续思考
对于html页面显示层次的语言包翻译,gettext能很方便的完成。但对于写入数据库的数据做多语言。如产品分类名,中文显示中文,英文显示英文。一般做法是多存一个字段,管理员填写分类的时候,填写中英名。当然,也有在数据库用language_id区分,还要新建一张产品名表。
如果只填写了一种语言。非要用程序来做处理,也是可以。如
<code>
<?php
/**
* ToTreeArray 处理无穷层次的函数
*
* @param mixed $rows 数据库查询出来分类数组
* @param mixed $ParentID 父ID如’parent_id’
* @param mixed $ID 类型ID如’type_id’
* @param mixed $Lang 需要翻译字段如’type_name’
* @static
* @access public
* @return array
*/
public static function ToTreeArray($rows,$ParentID,$ID,$Lang=false) {
if ( !$rows ) return array();
$tree = array();
$index = array();
foreach ( $rows as $row ) {
if ( $Lang ) { $row[$Lang] = _($row[$Lang]); } //对于分类而言,翻译分类名。
if ( $row[$ParentID] == 0 ) {
$i = count($tree);
$tree[$i] = $row;
$index[$row[$ID]] = & $tree[$i];
} else {
$i = count($index[$row[$ParentID]]['Child']);
$index[$row[$ParentID]]['Child'][$i] = $row;
$index[$row[$ID]] = & $index[$row[$ParentID]]['Child'][$i];
}
}
return $tree;
}
?>
</code>
此类做法还需探讨
本文链接地址: php+gettext多多语言的探讨
原创文章,转载请注明出处,否则视为侵权。
posted 3 months ago
gettext这个东西我当时没用好。。
后来不得不每个语言建个文件夹。。麻烦死了额
posted 3 months ago
忒深奥了,偶基本上看不懂。