16十二/090
使用 GetText 扩展实现国际化支持
首先,我们构建一个简单的 I18n 工具类 I18n.php:
class I18n
{
/**
* 默认语言
*
* @var string
*/
const DEFAULT_LOCALE = 'zh_CN';
/**
* 默认编码
*
* @var string
*/
const DEFAULT_CHARSET = 'UTF-8';
/**
* 单实例对象序列
*
* @var array
*/
private static $instances = array();
/**
* 当前语言
*
* @var string
*/
private static $locale;
/**
* 当前域
*
* @var string
*/
private $domain;
/**
* 格式化索引
*
* @param string $key
* @return string
*/
public static function quote($key)
{
return '/\{'.$key.'\}/';
}
/**
* 构造函数
*
* @param string $domain
*/
private function __construct($domain)
{
$this->domain = $domain;
bind_textdomain_codeset($this->domain, self::DEFAULT_CHARSET);
bindtextdomain($this->domain, LOCALE_DIR);
}
/**
* 获取格式化后的文本
*
* @param string $key
* @param array $params
* @return string
*/
public function _($key, $params = null)
{
$text = dgettext($this->domain, $key);
if (empty($params))
{
return $text;
} else {
return preg_replace(
array_map('I18n::quote', array_keys($params)),
array_values($params),
$text
);
}
}
/**
* 取得一个单实例I18n对象
*
* @param string $domain
* @return I18n
*/
public static function getInstance($domain)
{
if (empty(self::$locale))
{
self::setLocale(self::DEFAULT_LOCALE);
}
if (!array_key_exists($domain, self::$instances))
{
self::$instances[$domain] = new I18n($domain);
}
return self::$instances[$domain];
}
/**
* 设置I18n语言
*
* @param string $locale
*/
public static function setLocale($locale)
{
self::$locale = $locale;
setlocale(LC_ALL, $locale);
}
}
然后我们再生成 2 个用于测试的 po 文件。
首先是中文的语言文件 locale\zh_CN\LC_MESSAGES\message.po:
msgid "" msgstr "" "Project-Id-Version: message\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-06-12 17:26+0800\n" "PO-Revision-Date: 2009-12-15 20:39+0800\n" "Last-Translator: Zivn\n" "Language-Team: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Chinese\n" "X-Poedit-Country: CHINA\n" "X-Poedit-SourceCharset: utf-8\n" msgid "testMsg" msgstr "这是一条测试信息!你好,{name}!" msgid "userName" msgstr "火星梅梅"
然后是英文的语言文件 locale\en_US\LC_MESSAGES\message.po:
"Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2008-06-12 17:26+0800\n" "PO-Revision-Date: 2009-12-15 20:40+0800\n" "Last-Translator: Zivn\n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: English\n" "X-Poedit-Country: AMERICAN SAMOA\n" "X-Poedit-SourceCharset: utf-8\n" msgid "testMsg" msgstr "This is a test message!Hello,{name}!" msgid "userName" msgstr "zivn"
记得要生成二进制的 mo 文件哦。
好了,最后是我们用来测试的主文件:
define('ROOT_PATH', realpath('.'));
define('LOCALE_DIR', ROOT_PATH . DIRECTORY_SEPARATOR . 'locale');
$i18n = I18n::getInstance('message');
// Output: 这是一条测试信息!你好,火星梅梅!
echo $i18n->_('testMsg', array('name' => $i18n->_('userName')))."\n";
// Change Locale
I18n::setLocale('en_US');
// Output: This is a test message!Hello,zivn!
echo $i18n->_('testMsg', array('name' => $i18n->_('userName')))."\n";