app.brand
nav.index
nav.about
user.sign.in
ThinkPHP MySQL使用utf8_general_ci字符集导致中文排序混乱
首先,要说一下MySQL这个大坑…MySQL中的UTF-8并不是真正的UTF-8,只支持最多三个字节的字符,这个BUG没有修复,取而代之(不肯认错)提供了utf8mb4这个字符集…具体请看 然后使用了UTF-8后,发现中文排序混乱,出现这个问题的原因是因为MySQL在查询字符串时是大小写不敏感的,在编绎MySQL时一般以ISO-8859字符集作为默认的字符集,因此在比较过程中中文编码字符大小写转换造成了这种现象。 解决方案有很多,以下几种思路: 1.对于包含中文的字段加上”binary”属性,使之作为二进制比较,例如将`name char(10)`改成`name char(10) binary`。如果你使用源码编译MySQL,可以编译MySQL时使用`–with–charset = gbk`参数,这样MySQL就会直接支持中文查找和排序了(默认的是latin1)。也可以用`extra-charsets = gb2312,gbk` 来加入多个字符集。 2.如果不想对表结构进行修改或者重新编译MySQL,也可以在查询语句的`order by`部分使用CONVERT函数来强制MySQL按中文排序(UTF8 默认校对集是utf8_general_ci)。比如: ```sql select * from table_name order by CONVERT(ChineseColumnName USING GBK); ``` 我选了第二种方案来操作,结果又带出来个坑:在前段传参时候使用`order = 'CONVERT(ChineseColumnName USING GBK)'`,结果ThinkPHP直接报错。一开始以为是不是不能这么用,然后查了半天无果,用`fetchSql(true)`方法输出MySQL语句一看,乖乖,怎么order这里只剩下USING前面的部分了,` GBK)`这右边部分屁股消失了,导致MySQL语句出现明显的语法错误。继续查看问题,网上有说ThinkPHP库里的ViewModel.class.php文件,在checkOrder方法这里有个trim()的遗漏,填补即可,一激动: ![](/storage/0/article/20220504/82aa78102f4259b36c13bf26060b8579.png) 仔细看看我的文件目录和他不一样啊,他是www\ThinkPHP\Extend\Model\ViewModel.class.php,我是www\ThinkPHP\Library\Think\Modal\ViewModel.class.php,估计差了几个版本。然后我的文件里,trim()已经有了,Boom…我陷入了沉思…仔细看方法,实际上是对字符串进行了切割,而我现在的字符串,有3个空格,他只用了前两个…我TMD…改源码吧不太想,然后又查了查,突然看到人家用了个array(),哦!对哦!他不是判断是否字符串再处理么,我用数组不就好了。果然,妥妥的!
data.update.last
sys.time.ago
punc.commaarticle.create.bypunc.commaarticle.file.inpunc.colon
ThinkPHP
punc.caesura
MySQL
©app.copyright.year
app.author
·
app.ICP
sys.donate
alipay._self
wechat._self