richie
(Richie Liu9)
1
参照了Yii文档中的国际化部分,有点理解。
但是,个人认为,Web应用的国际化问题仍然没有彻底的解决。
Yii提供了语种的翻译支持,但是这仅仅只能满足小部分的业务需求。
当然,Yii也提供了CDbMessageSource作为数据库方面的翻译。
但是这跟CPhpMessageSource没什么区别,只是把翻译好的数据放入数据库了。
我的问题是这样的,比如产品类别信息的国际化。
我可以建立两张表,一张中文,一张英文。
或者只建立一张表,添加语种字段,标识语种。
问题来了:
当zh_cn的浏览器打开我的网页时,显示的商品类别必然是中文的。
当en_us的浏览器打开我的页面时,显示的商品类别必然是英文的。
那么,我如何自动的选择数据表,并读取这些数据呢?
现在做web开发的越来越依赖于数据库了,恨不得把所有东西都向数据库中放。
当然,上面的问题解决并不难,我只要判断用户的语言首选项,
然后动态的选择表,然后读取数据,也可以,照样可以解决问题。
问题的严重性在于,我的数据库是很庞大的。
我必须要根据语种去建立N张重复的表吗?那还不如直接按语种新建数据库呢。
或者不厌其烦的为每个表都增加语种字段?
相信上面的两种方案在实际开发中定是头疼的问题。
根据语种选择相应的数据库表也许改写Yii框架并不是很难,
但是如果我想要动态的指定数据库表呢,
比如我是zh_cn,但是我就想往en_us的表中写英文。
怎么办呢?
大家晓得,Yii支持数据库就两个,一个是DAO,一个就是AR
不用了,DAO灵活性很强大,完全可以根据上面的业务要求实现,但是太繁琐了。
AR用的就让人还有点意思,但是AR类的设计让人有点摸不到头脑,因为AR类针对性太强,伸缩性就差了点。
做过国际话的朋友可以交流一下,在下不甚感激!
讨教中。。。。。。
richie
(Richie Liu9)
2
补充说明:
我说的可能有点迷茫,有点乱。
在上面的国际化问题中,我根本没有涉及到一点翻译的问题。
意思就是说我并不赞成使用Yii::t()这样的方法去资源文件中读取翻译好的文件。
为什么,举个最简单的例子,就是我的页面字符串长度的显示问题。
谁知道我的中文翻译成某个国家语言后的长度是多大,倒是页面偏了,或者换行了。
我可不想看到那样的结果。
我更倾向于使用CApplication::findLocalizedFile()去找翻译好的整个页面。
这样我们可以针对每个语种设计合适的页面,然后显示问题一点没有问题。
但是,我更更倾向于使用Theme,主题在我的工程里面多了一个角色,那就是语种。
不用多说,相信大家都知道。
然后说说我数据库的问题。
目前我们数据库倾向于根据语种设计多个数据库。
zh_cn和en_us两个数据库,当然还有其他语种的。
每个数据库的数据表结构完全一样。
唯一不同的就是每个语种数据库存放属于自己语言的数据信息。
现在我可以使用DAO去动态选择或者参数指定特定语种的数据库连接
来完成数据库的所有操作。
因为数据库表结构一样,所以我只关心数据库连接,而不担心CURD的操作。
问题在于AR类我就无奈了,有点不知所措了。
当然动态改变AR类的数据库连接,也没有问题,改改源代码就完成了。
关键在于没有办法参数指定AR类的数据库连接,当然也可以更改,
但是也学就把AR类改的面目全非了。
我在想,是否我们国际化的设计初衷就是错误的呢?
希望能得到有经验人士的帮助,给点建议也可以啊!
先谢谢了!
richie
(Richie Liu9)
3
新的解决方案:使用表前缀区分语种!
例如数据库存在两个表:
cn_customer
en_customer
两张表的结构完全一样,就是表名的前缀不同,这是针对国际化问题设置的。
因为这两张表的结构相同,所以它可以使用同一个AR类去操作,只是操作的表前缀不同,
若前缀是’cn’,则对cn_customer表进行CURD操作。
数据库配置:
‘db’=>array(
'connectionString' => 'mysql:host=localhost;dbname=test',
'emulatePrepare' => true,
'username' => 'root',
'password' => '123456',
'charset' => 'utf8',
'tablePrefix'=>'cn_',
),
我默认的表前缀是’cn_’,注意一定要有下滑杠。
怎么动态指定表前缀,实时的对两张表操作呢?很简单,我只需要修改’db’组件的’tablePrefix’属性即可,感谢强这里将’tablePrefix’设置成可写属性。代码如下:
$db = Yii::app()->db;
$db->tablePrefix = ‘en_’;
//$customer = Customer::model()->findByPk(1);
//$this->render(‘index’,array(‘customer’=>$customer));
$customer = new Customer;
$customer->name = ‘zhognwen’;
$customer->save();
这种情况下,我们AR类使用起来就不受干扰的多了!
sharehua
(8080268)
4
你这是 一个国家一个应用吗?那你一个国家用一套theme 应该可以解决问题吧?只需要 修改数据库和theme的名字。
richie
(Richie Liu9)
5
谢谢你的回复!
不是的,我就一个应用啊,但是要适应多语言的情况。
使用theme可以解决界面语种的问题,但是不能解决数据库的问题啊。
如果是中文的页面就应该读取中文的数据,
英文的界面应该读取英文的数据。
问题是我不晓得数据库怎么设计。
目前的最新设计是一个数据库。
没个表前面加语种前缀。
比如product表吧,就有三个:
cn_product
en_product
fr_product
每次进行数据库CURD操作的时候,
都需要修改db的表前缀属性。
就是这样!
不错,我也是这样想的。我用theme 来做,然后用数据表前缀来区别