Bol*_*wyn 11 php localization internationalization php-gettext
考虑编写一个PHP库,它将通过Packagist或Pear发布.它适用于在任意设置中使用它的同行开发人员.
该库将包含为客户端确定的一些状态消息.如何使此代码国际化,以便使用该库的开发人员可以尽可能自由地插入自己的本地化方法?我不想假设任何东西,特别是不强迫开发人员使用gettext.
要处理一个例子,让我们来看看这个类:
class Example {
protected $message = "I'd like to be translated in your client's language.";
public function callMe() {
return $this->message;
}
public function callMeToo($user) {
return sprintf('Hi %s, nice to meet you!', $user);
}
}
Run Code Online (Sandbox Code Playgroud)
这里有两个问题:如何将private标记$message为翻译,以及如何允许开发人员在内部对字符串进行本地化callMeToo()?
一个(非常不方便)选项是,在构造函数中要求一些i18n方法,如下所示:
public function __construct($i18n) {
$this->i18n = $i18n;
$this->message = $this->i18n($this->message);
}
public function callMeToo($user) {
return sprintf($this->i18n('Hi %s, nice to meet you!'), $user);
}
Run Code Online (Sandbox Code Playgroud)
但我非常希望有一个更优雅的解决方案.
编辑1:除了简单的字符串替换外,i18n的字段很宽.前提是,我不想在我的库中打包任何i18n解决方案,或强迫用户专门选择一个以满足我的代码.
然后,我如何构建我的代码,以便为不同方面提供最佳和最灵活的本地化:字符串翻译,数字和货币格式,日期和时间,......?假设一个或另一个显示为我的库的输出.消费者可以在哪个位置或界面插入她的本地化解决方案?
最常用的解决方案是字符串文件.如下所示:
# library
class Foo {
public function __construct($lang = 'en') {
$this->strings = require('path/to/langfile.' . $lang . '.php');
$this->message = $this->strings['callMeToo'];
}
public function callMeToo($user) {
return sprintf($this->strings['callMeToo'], $user);
}
}
# strings file
return Array(
'callMeToo' => 'Hi %s, nice to meet you!'
);
Run Code Online (Sandbox Code Playgroud)
为了避免$this->message作业,你可以使用魔法吸气剂:
# library again
class Foo {
# … code from above
function __get($name) {
if(!empty($this->strings[$name])) {
return $this->strings[$name];
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以添加一个loadStrings方法,该方法从用户获取字符串数组并将其与内部字符串表合并.
编辑1:为了获得更大的灵活性,我会稍微改变上述方法.我会添加一个翻译函数作为对象属性,并在我想要本地化字符串时始终调用它.默认函数只查找字符串表中的字符串,如果找不到本地化字符串,则返回值本身,就像gettext一样.然后,使用您的库的开发人员可以将功能更改为他自己提供的功能,以执行完全不同的本地化方法.
日期本地化不是问题.设置区域设置取决于您的库使用的软件.格式本身是一个本地化的字符串,例如$this->translate('%Y-%m-%d')将返回日期格式字符串的本地化版本.
通过设置正确的区域设置和使用类似的功能来完成数字本地化sprintf().
但是,货币本地化是一个问题.我认为最好的方法是添加货币转换功能(并且,也许是为了更好的灵活性,另一个数字格式化功能),如果开发人员想要更改货币格式,可以覆盖该功能.或者,您也可以为货币实现格式字符串.例如%CUR %.02f- 在此示例中,您将替换%CUR为货币符号.货币符号本身也是本地化字符串.
编辑2:如果你不想使用setlocale你必须做很多工作......基本上你必须重写strftime()并sprintf()实现本地化的日期和数字.当然可能,但很多工作.
| 归档时间: |
|
| 查看次数: |
1160 次 |
| 最近记录: |