多语言的处理--一个有用的缓存扩展
时间:2010-09-18 来源:库从志
本文是工作中碰到多语言处理的经验总结,将其分享,给碰到类似的问题的有一些帮助。
第一次碰到多语言处理是一个网络广告平台项目,类似于google的ansendse,阿里妈妈;因为是给国外的公司开发,所以当时基本要求是支持中英文,当然以后会添加其他的语言。当时系统是根据用户使用的语言环境来确定使用何种语言,当然前端也有一个用户可以选择的下拉列表。程序的实现方法是:将页面上所有出现语言的地方在tpl模板里面使用label标记替换,在程序里面使用特定的语言将这些label换掉。
这些label和具体的语言就是一个二维数组,键是label,值就是这些具体的语言符号。当时这个系统大概有1000多条这样数据,具体的处理的逻辑:将用户的语言和这些label从数据库中取出,组成数组后放在GLOBAL变量中,然后生成页面的时候替换掉。
问题:每一次用户请求用户就要从数据库中取出所有的值,然后替换。
最近在开发社区游戏时,由于要实现国际化多语言版本,也要处理语言问题。我们在这个地方使用自己开发的文件缓存系统,这里我将这个代码(不是真实的)大概写在下面:
function _T($text)
{
$lang = $cfg['lang'];
if(!empty($GLOBAL['lang'][$text])
return $GLOBAL['lang'][$text];
$cache = $app->cache('filecache');
$lang_all = $cache->get($lang);
if(!is_array($lang_all)) { $lang_all_db = $app->getArray("select `key`, $lang from lang"); foreach($lang_all_db as $k=>$v) { $lang_all[$k] = $v; } $cache->set($lang, $lang_all); } else $GLOBAL['lang'] = $lang_all; returun $lang_all[$text];
}
程序的逻辑是: 每个请求如果需要多语言处理的时候,第一次就将所有的内容从数据库中取得,建立一个公用的文件缓存,然后每个请求会读文件缓存,将所有的结果保存在全局变量中,而这个翻译大概需要460k左右的内存,几乎每个请求都需要使用到这个函数,所以每个请求就会占用460k的内存。
由于在更新语言的时候,需要将缓存文件删除,此时如果多个访问并发执行该函数的时候,就会有请求创建文件失败,造成内存泄漏,php crush了。
后来将这个文件缓存改为memcache,发现memcache占用的内存更多,当然我这个时候也把全局变量也去掉。同时初始化memecache这个键值的时候,还常常设置失败,严重影响系统稳定性。
最后发现chdb这个php扩展(官方地址),它能很好地解决这些问题,整个数组初始化好之后,当我们需要取出具体的某一条的时候,它只取出那一条,并放在内存中,可以供多个请求公用。
例如:
$lang = array('A'=>'你好', 'B'=>'中国', 。。。。。);
chdb_create('data.chdb', $lang); //设置一次
$chdb = new chdb('data.chdb');
$value1 = $chdb->get('A');
$value2 = $chdb->get('B'); //获取具体的值
后来经过测试在一次取200条的时候,这种方法要比上面的稍快10%,当然使用的内存也少很多。
这个插件目前只有linux版,另外在编译的时候需要libcmph