关于Yii CStringValidator使用strlen和mb_strlen的一些来龙去脉

缘起:我们将一个早年(2010?)的Yii应用从服务器A迁移到服务器B之后,发现几乎所有关于字符串长度的Validator都出问题了,每个汉字都被当成“2个字符”计算。我们做了一系列调查,对比了两台服务器LAMP环境配置上的差别,发现老服务器的php.ini文件中mbstring.func_overload被设置为7(很可怕),而新服务器则没有这样设置,于是试着追踪了一下来龙去脉,将发现分享一下。

这个问题大概最早是一位叫shuwato的日本人在09年提出来的,他发现Yii的CStringValidator没有按照预想去计算字符数(Yii 1.0.4),于是给Yii开发者提了一个BUG:http://code.google.com/p/yii/issues/detail?id=329

“强”(Yii的核心设计师)给出的解决方法竟然就是建议他修改php.ini,让mb系的str函数去覆盖标准的str函数(汗颜尴尬),可能当时该应用的开发人员修改mbstring.func_overload参数,也和这个issue有关。无论如何这是一个杀伤力很大的改动,所有使用php标准str函数的地方都会受影响,换言之所有部署在该服务器的PHP应用都会受影响(如果其他应用按PHP标准str函数的行为去设计程序的,就可能导致bug)。

shuwato显然对强的回复不满,就跑到Yii的论坛里面去发了一个帖子抱怨:
http://www.yiiframework.com/forum/index.php/topic/2205-stringvalidator%E3%81%AE%E3%83%9E%E3%83%AB%E3%83%81%E3%83%90%E3%82%A4%E3%83%88%E5%AF%BE%E5%BF%9C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

用日文发的内容,没必要细看,我简介如下吧:他当时不接受强的建议,提出另外三个构想,一是修改Yii framework的代码;二是自己写一个validator代替
CStringValidator ;三是修改 .htaccess的设置。

关于[
.htaccess]我不是很理解,我猜想是使用应用级的[ .htaccess]文件来覆盖php.ini的某些参数,这样就把影响面缩小到一个具体的应用,不影响部署在同服务器的其他应用(有待考证)。

后面的iwasaki回复提到,构想一,如果升级了框架,还要担心忘了改过人家代码,导致别的bug;
[.htaccess]也一样,如果部署在其他地方忘了改,也出问题;构想三,自写validator是推荐的。

一年半过去以后,一个叫jamband的人提到,他使用Yii 1.1.4,可以通过一个encoding属性回避这个问题,
代码写起来像 array('title', 'length', 'max'=>50, 'encoding' => 'utf8'),意思是自己指定编码(对于非ASCII等单字节编码)的话,Yii就会调用 mb_strlen去算字符数。

※encoding参数应该是从Yii 1.1.1开始提供的(参考Yii的changelog):

http://code.google.com/p/yii/source/browse/trunk/CHANGELOG#231
- Enh #392: Added CStringValidator::encoding to support checking the length of multibyte strings (Qiang)

jamband后来又追加了一个说明,说从Yii 1.1.7开始,Yii总算修改了这个让人苦恼的行为,即使不改mbstring.func_overload设置,也不指定encoding属性,对于多字节字符,也会按照mb_strlen去计算字符数了。
- Enh: CStringValidator now uses application charset by default if mb_strlen is available (Sam Dark)

application charset应该指的是config/main.php里面指定的language属性。

至此总算天下太平了。。我们后来做基于Yii的项目时候应该是挺幸运的,赶上了当时最新的Yii 1.1.7(后来换成1.1.8),如果我们早三个月(1.1.7之前)动工的话,一样要面对早期开发人员当时遇到的问题,如果不看到shuwato发的帖子以及后面jamband的回复,恐怕我们也一样会去修改php.ini来解决问题。

由此足见不管是Yii之于强,还是这些项目之于我们,时空因缘都不可思议。今天遇到的这个问题,相当于带着我们时光倒流,重新看到了Yii这样一个框架的成长和变化,各个历史时间点上的种种制约因素,以及使用它的人所做的种种思考,我们所做的事情,大概也有几分相似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值