1   主题

主要记录 php与mysql在大小写转换上的区别 问题

2   问题

mysql的大写转小写函数( lower ) 与 php的大写转小写函数( mb_strtolower , strtolower 这个很low,就不说了 )在大部分case上是一致的,但是存在一些例外

case:

$str = "High School D×DⅡ ";

echo mb_strtolower( $str, "UTF-8") . "\n";

php 的输出为:

high school d×dⅡ

而mysql的输出为:

high school d×dⅱ

当然 小写转大写也是存在这个问题的

关于 mb_strtolower 对某些特殊字符不转换为小写的问题,php 官网上也有人提出来过:

http://php.net/manual/en/function.mb-strtolower.php

在上面的讨论里,也说过 mb_strtolower 要比 mysql的大写转小写函数( lower ) 慢 -_-||

3   做的事情

因为业务需求,需要保证两者的一致性,所以把mysql的大小写转换的代码( mysql-5.1.74 )扣了出来,搞成一个php扩展,提供了额外的函数来实现目的

case:

$str = "High School D×DⅡ ";

$timeMB = microtime(true);
$resMb = mb_strtolower( $str, "UTF-8");
$timeMB = microtime(true) - $timeMB;

$timeSQL = microtime(true);
$resSQL = strtolower_utf8_ext($str);
$timeSQL = microtime(true) - $timeSQL;

echo "mbTime:" . sprintf("%.5f",$timeMB)." \n";
echo "sqlTime:" . sprintf("%.5f",$timeSQL)."\n";

echo "mbRes:" . $resMb . "\n";
echo "sqlRes:" . $resSQL . "\n";

result:

mbTime:0.00004
sqlTime:0.00001
mbRes:high school d×dⅡ
sqlRes:high school d×dⅱ

性能差别case

$str = "High School D×DⅡ ";

$timeMB = microtime(true);
for($i=0;$i<30000;$i++)
    $resMb = mb_strtolower( $str, "UTF-8");
$timeMB = microtime(true) - $timeMB;

$timeSQL = microtime(true);
for($i=0;$i<30000;$i++)
    $resSQL = strtolower_utf8_ext($str);
$timeSQL = microtime(true) - $timeSQL;

echo "mbTime: " . sprintf("%.5f",$timeMB)." \n";
echo "sqlTime: " . sprintf("%.5f",$timeSQL)."\n";

result:

mbTime: 0.18481
sqlTime: 0.01055

PS: 因为只取了一部分mysql的源码,所以注释了一部分东西 -_-||

另外,发现在不同的php版本下注释的东西也不太一样

php-5.4.24编译的好好的,到php-5.4.35下编译又会报错,根据编译错误提示注释掉 lib/m_string.h 里的某个函数就好了 -_-||