我正在为我的网站做一个语言页面,将所有文本放在变量中,例如:
if($language=='en') {
lang[1]="Welcome, ".$user."!";
lang[2]="You have earned ".$pts." pts yesterday";
}
elseif($language=='fr') {
lang[1]="Bienvenue, ".$user."!";
lang[2]="Vous avez remporté ".$pts." pts hier";
}
我将此信息包含在每个页面的顶部。然而,问题是在许多页面中,$ lang [X]变量中的一些变量(例如$ user或$ pts)仅在它们的echo行之前声明了几行,或者它们甚至改变了几行在同一页面内的时间,所以当通过include加载语言变量时,它们在那一刻取值$ user或$ pts,而不是在它们的回声时刻。
有没有办法以这样一种方式使用这种技术:$ lang [X]中的变量是在它们的回声时刻拍摄的,而不是在它们的include()时刻?
答案 0 :(得分:3)
不要使用变量名使用标记并翻译字符串:
function _t($index, $language, $vars = array()){
if($language=='en') {
lang[1]="Welcome, %user%!";
lang[2]="You have earned %pts% pts yesterday";
}
elseif($language=='fr') {
lang[1]="Bienvenue, %user%!";
lang[2]="Vous avez remporté %pts% pts hier";
}
return strtr($lang[$index], $vars);
}
echo _t(1, 'en', array('%user%' => 'John D.'));
但是我不会从头开始做这样的事情我会使用支持传统i18n / l10n方法的东西,比如gettext
或Zend_Translate
(它使用gettext但支持多种数据格式)。这样做有标准化。如果你坚持使用翻译的数据格式的例外标准之一和转换方法,你会在很多方面变得更好。更不用说它的工作量会减少: - )
答案 1 :(得分:2)
不容易。常见的解决方法是在翻译的字符串中使用%s
占位符:
elseif ($language=='fr') {
$lang[1]="Bienvenue, %s!";
然后用sprintf
填充它们:
echo sprintf($lang[1], $user);
话虽如此,您应该考虑gettext
方案,而不是 数字索引 $lang[]
数组并包含脚本。 (这很容易变得难以维持......)
答案 2 :(得分:1)
您可以查看sprintf。您可以使用"Welcome, ".$user."!"
而不是"Welcome, %s!"
。
答案 3 :(得分:1)
也许您可以使用sprintf而不是echo,只使用占位符而不是实际值:
像这样:if($language='en') {
lang[1]="Welcome, %s!";
lang[2]="You have earned %d pts yesterday";
}
elseif($language='fr') {
lang[1]="Bienvenue, %s!";
lang[2]="Vous avez remporté %d pts hier";
}
而且你可以做到
sprintf (lang[1], $user);
答案 4 :(得分:0)
我还使用一个开关来提高可读性,让它回归到默认语言:
switch($language) {
case 'fr':
lang[1]="Bienvenue, %s!";
lang[2]="Vous avez remporté %s pts hier";
break;
case 'en':
default:
lang[1]="Welcome, %s!";
lang[2]="You have earned %s pts yesterday";
}
echo sprintf($lang[1], $user);
php 5.3中的一些新内容:http://devzone.zend.com/article/4799