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 简单示例、源代码与编辑器

1465567882

点此到Github查看源代码

新建.po与.mo的编辑器推荐使用poedit,网址:https://poedit.net/

0x06 结语

我还是PHP与HTML的新手,同时尝试使用bootstrap对daloRADIUS进行重构,如果感兴趣的朋友也可以到我Github去看看,欢迎大家指出错误。

0x07 相关网站