IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

使用gettext来支持PHP的多语言

风雪之隅 2009-10-29 21:29:52 累计浏览 39,245 次
本机暂存

开发多语言的Web应用是一件非常困难的事,各个国家的字符集的编码方式、货币符号、日期格式、数字格式、文字表现都各不相同.

我们今天用一个简单的实例说明一下在PHP中的getText的用法(getText是一系列的工具和库函数,帮助程序员和翻译人员开发多语言软件的), 从而实现PHP的i18n.

现在, 我们假设要显示一个返回主页的link:

以下是代码片段:
//home.php:
$str = ’home’;

print <<<HTML
<a href="#">{$str}</a>
HTML;

下面开启我们多语言的开发之旅:

创建pot文件,pot是Portable Object Template的首字母缩写,与po对应的是mo,mo是Machine Object的首字母缩写。前者意指原始的字符串文件,一般用于给翻译人员去修改的,后者则是与机器相关的,一般是供程序读取。可以手工创建pot文件,也可以通过xgettext从代码中抽取字符串来产生。这里是用xgettext来产生的:

以下是代码片段:
xgettext -a home.php -o home.pot

运行该命令后,我们发现,在当前目录下,产生了一个名home.pot的文件,打开该文件,可以看到:

以下是代码片段:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE’S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-07-23 20:56+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: home.php:2
msgid "home"
msgstr ""

根据pot产生不同语言的po文件,这里我们先产生一个简体中文的po文件:

以下是代码片段:
export LANG=zh_CN.gb2312
msginit -l zh_CN.gb2312 -i home.pot

运行该命令后,我们发现,在当前目录下,产生了一个名zh_CN.po的文件,打开该文件,可以看到:

以下是代码片段:
# Chinese translations for PACKAGE package
# PACKAGE 软件包的简体中文翻译.
# Copyright (C) 2009 THE PACKAGE’S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#  <huixinchen@localhost.localdomain>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-07-23 20:56+0800\n"
"PO-Revision-Date: 2009-07-23 21:00+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Chinese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=GB2312\n"
"Content-Transfer-Encoding: 8bit\n"

#: test.php:2
msgid "home"
msgstr ""

翻译zh_CN.po里对应的字符串为中文:

以下是代码片段:
# Chinese translations for PACKAGE package
# PACKAGE 软件包的简体中文翻译.
# Copyright (C) 2009 THE PACKAGE’S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#  <huixinchen@localhost.localdomain>, 2009.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-07-23 20:56+0800\n"
"PO-Revision-Date: 2009-07-23 21:00+0800\n"
"Last-Translator:  <huixinchen@localhost.localdomain>\n"
"Language-Team: Chinese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=GB2312\n"
"Content-Transfer-Encoding: 8bit\n"

#: test.php:2
msgid "home"
msgstr "主页"

根据po文件生成mo文件。

以下是代码片段:
msgfmt zh_CN.po -o zh_CN.mo

运行该命令后,我们发现,在当前目录下,产生了一个名zh_CN.mo的文件。它是二进制的,不能用文本编辑器打开。

安装mo文件到特定目录中:

以下是代码片段:
cp -f zh_CN.mo .local/LC_MESSAGES/home.mo

修改程序。

以下是代码片段:
setlocale(LC_ALL, ’zh_CN’);

// Specify location of translation tables
bindtextdomain("home", ".");

// Choose domain
textdomain("home");

// Translation is looking for in ./locale/zh_CN/LC_MESSAGES/home.mo now

$str = gettext(’home’); //也可以使用_(’home’)

print <<<HTML
<a href="#">{$str}</a>
HTML;

运行这个脚本, 看看, 是不是输出正确的中文了呢?

添加其它语言也很容易,不需要修改程序,只需要像对待中文一样,生成一个mo文件,并安装到系统中对应的目录即可。切换不同的语言仅仅是修改当前的locale就行了。

同分类推荐文章

  1. Go 实验特性详解 (2026-06-21 10:05:27)
  2. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)
  3. Loop Engineering 实践:我把 RDMA 开发库移植到 Go 语言,花费 239 块钱 (2026-06-17 04:00:24)

查看更多 后端 文章 →

建议继续学习

  1. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,144)
  2. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,395)
  3. 我的PHP,Python和Ruby之路 (累计阅读 13,122)
  4. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,773)
  5. 15个最好的免费开源电子商务平台 (累计阅读 12,511)
  6. Redis消息队列的若干实现方式 (累计阅读 12,064)
  7. 到底什么是MVC? (累计阅读 11,827)
  8. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,655)
  9. Rolling cURL: PHP并发最佳实践 (累计阅读 11,469)
  10. 你必须了解的Session的本质 (累计阅读 11,409)