PHP判断字符串编码函数mb_detect_encoding总结

php中可以使用 mb_detect_encoding() 函数来判断字符串是什么编码的。

当在php中使用mb_detect_encoding函数进行编码识别时,很多人都碰到过识别编码有误的问题,例如对与GB2312和UTF-8,或者UTF-8和GBK(这里主要是对于cp936的判断),网上说是由于字符短时mb_detect_encoding会出现误判。

代码如下:
$encode = mb_detect_encoding($keytitle, array("ASCII","UTF-8","GB2312","GBK","BIG5"));
if($encode == "UTF-8"){
    $keytitle = iconv("UTF-8","GBK",$keytitle);
}

这段代码的作用是检测字符串的编码是否UTF-8,是的话就转换为GBK。

可是当 $keytitle = “%D0%BE%C6%AC”;时。检测结果却是UTF-8.这个bug其实不算是bug,写程序时也不应当过于依赖mb_detect_encoding,当字符串较短时,检测结果产生偏差的可能性很大。
解决办法,代码如下:
$encode = mb_detect_encoding($keytitle, array("ASCII","GB2312","GBK","UTF-8");

三个参数分别是:被检测的输入变量、编码方式的检测顺序(一旦为真,后面自动忽略)、strict模式对编码检测的顺序进行调整,将最大可能性放在前面,这样减少被错误转换的机会。

一般要先排gb2312,当有GBK和UTF-8时,需要将常用的排列到前面。


另附一:PHP字符串编码的转换和判断


GBK 和 UTF-8 编码的转换是一个非常恶心的事情,比如像 PHP 中的 json_encode 本身根本不支持 GBK 形式的编码。有两个库函数能够支持编码的转换,通常能够想到的就是 iconv 函数,使用起来也非常爽:
iconv('GBK', 'UTF-8//IGNORE', '测试字符串'); // 将字符串由 GBK 编码转换为 UTF-8 编码

但 iconv 只能解决编码预先知道的情况,如果字符串编码未知,则需要先探测其编码,这时可能会用到 mb_string 扩展库:

mb_detect_encoding('测试字符串');

可是 mb_detect_encoding 存在一个硬伤,经常出现判断不准确的情况。或许这样就可以解决:

// 使用 iconv 转换并判断是否等值,效率不高
function is_utf8 ($str) {
    if ($str === iconv('UTF-8', 'UTF-8//IGNORE', $str)) {
        return 'UTF-8';
    }
}
// 多种编码的情况
function detect_encoding ($str) {
    foreach (array('GBK', 'UTF-8') as $v) {
        if ($str === iconv($v, $v . '//IGNORE', $str)) {
            return $v;
        }
    }
}

通过以上方式得到字符串编码信息后,就可以利用 iconv 或 mb_convert_encoding 来转换编码了。



另附二:PHP判断文件或字符串的编码方式mb_detect_encoding


注意:要把php.ini中 extension=php_mbstring.dll 前的;号去掉,重启apache就可以了。

我创建三个文件:text1.txt  text2.txt text3.txt

分别以ASCII UTF-8 UNICODE 的编码方式保存

代码如下:
<?php

    define ('UTF32_BIG_ENDIAN_BOM'   , chr(0x00) . chr(0x00) . chr(0xFE) . chr(0xFF));
    define ('UTF32_LITTLE_ENDIAN_BOM', chr(0xFF) . chr(0xFE) . chr(0x00) . chr(0x00));
    define ('UTF16_BIG_ENDIAN_BOM'   , chr(0xFE) . chr(0xFF));
    define ('UTF16_LITTLE_ENDIAN_BOM', chr(0xFF) . chr(0xFE));
    define ('UTF8_BOM'               , chr(0xEF) . chr(0xBB) . chr(0xBF));

    function detect_utf_encoding($text) {
        $first2 = substr($text, 0, 2);
        $first3 = substr($text, 0, 3);
        $first4 = substr($text, 0, 3);
      
        if ($first3 == UTF8_BOM) return 'UTF-8';
        elseif ($first4 == UTF32_BIG_ENDIAN_BOM) return 'UTF-32BE';
        elseif ($first4 == UTF32_LITTLE_ENDIAN_BOM) return 'UTF-32LE';
        elseif ($first2 == UTF16_BIG_ENDIAN_BOM) return 'UTF-16BE';
        elseif ($first2 == UTF16_LITTLE_ENDIAN_BOM) return 'UTF-16LE';
    }
    function getFileEncoding($str){
        $encoding=mb_detect_encoding($str);
        if(empty($encoding)){
            $encoding=detect_utf_encoding($str);
        }
        return $encoding;
    }
    $file = 'text1.txt';
    echo getFileEncoding(file_get_contents($file));  // 输出ASCII
    echo '<br />';

    $file = 'text2.txt';
    echo getFileEncoding(file_get_contents($file));  // 输出UTF-8
    echo '<br />';
    $file = 'text3.txt';
    echo getFileEncoding(file_get_contents($file));  // 输出UTF-16LE
    echo '<br />';

?>


php转换字符串编码 iconv与mb_convert_encoding的区别


你可能感兴趣的:(PHP,字符串,编码,判断)