0x01 前言
最近一周,我对daloRADIUS特别感兴趣,我想通过这款开源控制面板来管控一些服务的认证。我不想在服务器上安装Docker来使用ToughRADIUS,而这款daloRADIUS已经很久没更新了,所以我在Github将这个项目Fork到名下并创建一个For PHP7的分支。在取得愿编写者的同意后进行二次开发。
对于一款开源软件来说,各方面的便捷性都是很重要的,而实现多种语言却是重中之重。一个项目是否实现多语言发行,就决定了软件能走多远、辐射的范围有多广。
原作者也是将常用的词与短语都抽离出来写到同一个PHP文件中,但还是有些控制界面中的词与短语没抽离。在昨天我决定使用gettext作为提供多语言版本的途径。
0x02 什么是gettext
PHP的说明只有一句话:gettext函数实现了NLS (Native Language Support) API,他可以用来国际化您的PHP程序。
而GUN的解释就详细多了,毕竟这是GUN的项目,大概意思是:一般项目开发的界面和书面记录是以英语为基础,大多数人相比英语会更愿意使用或更熟悉自己的母语。可是开发者并不太愿意花时间去进行多语言的翻译,同时也不太现实。而一个可行的结构化翻译方案是大家所需要的… …
太长了,需要浏览全文的请移步至The Purpose of GNU gettext。
0x03 将gettext编译进你的PHP
编译PHP的时候通过添加以下选项即可:
--with-gettext[=DIR] #也可以选择不指定gettext所在的文件夹,直接通过以下命令添加 --with-gettext
完成后通过以下命令即可查询是否成功将gettext编译到PHP:
MacBook-Air:~ terence$ php -m | grep gettext gettext
这个模块不需要在没有任何设置,编译完成即可使用。
我使用的环境是MacBook,内置的PHP5和我通过brew安装的PHP7都是内置gettext。
0x04 在你的项目使用gettext
0x04.1 设定语言与翻译文件路径
#设置语言 $locale = 'zh_CN'; #设置路径 $locale_dir = './locale'; #设置环境变量的值 putenv('LC_ALL=' . $locale); #设置语言环境信息 setlocale(LC_ALL, $locale); #设置默认域 textdomain($domain); #设置域名称变量 $domain = "daloRADIUS"; #设置域对应的翻译文件所在的路径 bindtextdomain($domain, "./locale"); #设置域对应的字符编码 bind_textdomain_codeset($domain, 'UTF-8');
以下适用于多个域的情况:
#设置语言 $locale = 'zh_CN'; #设置路径 $locale_dir = './locale'; #设置环境变量的值 putenv('LC_ALL=' . $locale); #设置语言环境信息 setlocale(LC_ALL, $locale); #设置默认域 textdomain($domain); #设置域名称变量 $domain = "daloRADIUS"; #设置域对应的翻译文件所在的路径 bindtextdomain($domain, "./locale"); #设置域对应的字符编码 bind_textdomain_codeset($domain, 'UTF-8'); #设置域2名称变量 $domain2 = "daloRADIUS2"; #设置域2对应的翻译文件所在的路径 bindtextdomain($domain2, "./locale"); #设置域2对应的字符编码 bind_textdomain_codeset($domain2, 'UTF-8');
0x04.2 创建目录
目录结构应该是这样的:
$locale_dir/$locale/LC_MESSAGES/daloRADIUS.{po,mo} 相对应上面的配置,是这样的结构: root | locale | zh_CN | LC_MESSAGES | daloRADIUS.po | daloRADIUS.mo
0x04.3 定义可翻译文字
$user = "Curious gettext tester"; #_()与gettext()具有相同的功能 echo _("Let’s make the web multilingual."); echo _("We connect developers and translators around the globe on Lingohub for a fantastic localization experience."); echo sprintf(_('Welcome back, %1$s! Your last visit was on %2$s', $user, date('l')); #dgettext()与 _()的功能相似,但它可以根据域的设置而进行选择输出。 echo dgettext("example2", ""); // ngettext() is used when the plural form of the message is dependent on the count echo ngettext("%d page read.", "%d pages read.", 1); //outputs a form used for singular echo ngettext("%d page read.", "%d pages read.", 15); //outputs a form used when the count is 15
0x04.4 建立.po文件
以下是daloRADIUS.po文件的截取:
msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: 2016-06-10 04:20+0800\n" "PO-Revision-Date: 2016-06-10 04:21+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.8\n" "X-Poedit-Basepath: ../../..\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Poedit-SearchPath-0: login.php\n" #: login.php:8 msgid "RADIUS Management" msgstr "RADIUS 管理软件" #: login.php:9 msgid "Reporting | Accounting | Billing" msgstr "报告 | 统计 | 计费" #: login.php:11 msgid "daloRADIUS © 2007 by Liran Tal" msgstr "daloRADIUS 由 Liran Tal 于 2007年开发" #: login.php:12 msgid "Template design by TerenceChuen." msgstr "界面由 TerenceChuen 设计开发"
0x05 简单示例、源代码与编辑器
新建.po与.mo的编辑器推荐使用poedit,网址:https://poedit.net/
0x06 结语
我还是PHP与HTML的新手,同时尝试使用bootstrap对daloRADIUS进行重构,如果感兴趣的朋友也可以到我Github去看看,欢迎大家指出错误。