模板字符串。
此链接可能有所帮助: Does PHP have a feature like Python's template strings?
我的主要问题,是知道是否有更好的存储文字字符串的方法。
现在,这通常是通过一个文件夹(DIR)和 大量单个独立文件使用不同的字符串 完成的,具体取决于可能需要的内容,获取一个文件的内容,处理并将 {tags} 替换为值。
或者,最好在单个文件数组[] 中定义所有这些内容吗?
greetings.tpl.txt
['welcome'] = 'Welcome {firstname} {lastname}'.
['good_morning'] = 'Good morning {firstname}'.
['good_afternoon'] = 'Good afternoon {firstname}'.
这是另一个例子,https://github.com/oren/string-template-example/blob/master/template.txt
提前谢谢!包含解决方案的答案,说明应该使用include(" ../ file.php");从来没有接受过这里。一个解决方案,演示如何将已定义字符串的LIST读入数组。该定义已基于数组。
答案 0 :(得分:5)
要向模板添加值,您可以使用strtr
。示例如下:
$msg = strtr('Welcome {firstname} {lastname}', array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
关于存储字符串,您可以为每种语言保存一个数组,然后只加载相关的数组。例如。你将拥有一个包含2个文件的目录:
每个文件都应包含以下内容:
<?php
return (object) array(
'WELCOME' => 'Welcome {firstname} {lastname}'
);
当您需要翻译时,您可以执行以下操作:
$dictionary = include('language/en.php');
然后字典会有一个你可以解决的对象。改变上面的例子,它将是这样的:
$dic = include('language/en.php');
$msg = strtr($dic->WELCOME, array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
为避免在字典中没有模板时出现这种情况,可以使用带有默认文本的三元运算符:
$dic = include('language/en.php');
$tpl = $dic->WELCOME ?: 'Welcome {firstname} {lastname}';
$msg = strtr($tpl, array(
'{firstname}' => $user->getFistName(),
'{lastname}' => $user->getLastName()
));
人们通常可以在db中编辑文本,您可以使用简单的导出(例如var_export
)脚本从db同步到文件。
希望这有帮助。
答案 1 :(得分:1)
首先,看看gettext。它被广泛使用,并且有很多工具来处理翻译过程,比如xgettext和POEdit。在源代码中使用真正的英文字符串然后使用xgettext工具提取它们会更加舒适。 Gettext可以处理几乎所有语言的复数形式,这在使用简单的字符串数组时是不可能的。
与gettext结合使用的非常有用的功能是sprintf()(或printf(),如果你想直接输出文字)。
示例:
printf(gettext('Welcome %s %s.'), $firstname, $lastname);
printf(ngettext('You have %d new message.', 'You have %d new messages.',
$number_of_new_messages), $number_of_new_messages);
然后,当您想将其翻译成姓氏通常在名字前面的语言时,您可以使用:'Welcome %2$s, %1$s.'
第二个例子,复数形式,可以使用两个以上的字符串进行翻译,因为本地化文件的一部分是复数形式的排列方式。而对于英语,它是nplurals=2; plural=(n != 1);
,例如在捷克语中它是nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;
(三种形式,首先是一个项目,第二个是2到4个项目,第三个是其余项目)。例如爱尔兰语has five plural forms。
要从源代码中提取字符串,请使用xgettext -L php ...
。我建议使用适合您项目的确切命令编写短脚本,例如:
# assuming this file is in locales directory
# and source code in src directory
find ../src -type f -iname '*.php' > "files.list"
xgettext -L php --from-code 'UTF-8' -f "files.list" -o messages.pot
您可能希望使用-k参数添加自定义函数名称。
答案 2 :(得分:1)
好的约翰我会详细说明。
最好的方法是为每种语言创建一个包含文本数组定义的php文件,使用printf格式进行字符串替换。 如果文本量非常大,您可以考虑进一步分区。 (几MB通常很好)
这在生产中是有效的,假设操作系统具有良好调整的文件现金。稍微多一点,你使用数字索引到数组。
让php填充数组,然后自己动手,阅读文本文件会更有效率。毕竟,我认为,静态文本? 如果生产性能不是问题,请忽略这篇文章。
<强> greetings_tpl_en.php 强>
$text_tpl={
'welcome' => 'Welcome %s %s'
,'good_morning' => 'Good morning %s'
,'good_afternoon' => 'Good afternoon %s'
};
<强> your.php 强>
$language="en";
require('greetings_tpl_'. $language .'php');
....
printf($text_tpl['welcome'],$first_name,$last_name);
printf我是C语言的好遗产。 sprintf返回一个字符串而不是输出它。
您可以在此处找到php printf格式的完整说明:http://php.net/manual/en/function.sprintf.php
(当这个问题得到解决时,请再次阅读Josef Kufner的帖子。+ 1:c)
希望这有帮助吗?
答案 3 :(得分:0)
您可以将所有模板存储在一个关联数组中,还可以存储要替换占位符的变量,例如
$capt=array('welcome' => 'Welcome {firstname} {lastname}',
'good_morning' => 'Good morning {firstname}',
'good_afternoon' => 'Good afternoon {firstname}');
$vars=array('firstname'=>'Harry','lastname'=>'Potter', 'profession'=>'wizzard');
然后,您可以通过简单的preg_replace_callback
调用来转换句子,如
function repl($a){ global $vars;
return $vars[$a[1]];
}
function getcapt($type){ global $capt;
$str=$capt[$type];
$str=preg_replace_callback('/\{([^}]+)\}/','repl' ,$str);
echo "$str<br>";
}
getcapt('welcome');
getcapt('good_afternoon');
此示例将生成
Welcome Harry Potter
Good afternoon Harry