gbk和utf8编码自动识别方法[php版]

简介:

目前中文网页主流的编码为gbk和utf8两种编码。因此,我们做编码识别的前提是,编码不是gbk就是utf8.
编码自动识别的基本思想如下:
1.看给定的字节串是否符合utf8编码规则。如果不符合则为gbk编码。具体utf8编码规则件日志《utf8编码规则》。
2.如果给定的字节串中没有符合utf8三字节规则的,则为gbk编码。中文在utf8中占三个字节。
3.如果给定的字节串能对应上gbk编码中的中文,且无法对应上utf8编码中的中文,则为gbk编码。
4.特殊情况,特殊处理。如 “鏈條” 和 “瑷媄”。
总体思想是,先默认为utf8编码,再根据一些非utf8编码的情况逐步筛选。

准确率和效率还是不错的。20万多条query,1秒钟就可以处理完。

php代码如下:


function detect_encoding($str){
    $len = strlen($str);
    $encoding = "utf8";
    $is_utf8_chinese = false;
    for ($i = 0; $i < $len; $i++) { 
        if ( (ord($str[$i]) >> 7) > 0 ) { //非ascii字符
            if (ord($str[$i]) <= 191 ) {
                $encoding = "gbk0";
                break;
            } else if ( ord($str[$i]) <= 223 ) { //前两位为11
                if ( empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 ) { //紧跟后两位为10
                    $encoding = "gbk1";
                    break;
                } else {
                    $i += 1;
                }
            } else if ( ord($str[$i]) <= 239 ) { //前三位为111
                if ( empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2) { //紧跟后两位为10
                    $encoding = "gbk2";
                    break;
                } else {
                    $i += 2;
                    $is_utf8_chinese = true;
                }
            } else if ( ord($str[$i]) <= 247 ) { //前四位为1111
                if ( empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 or empty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2) { //紧跟后两位为10
                    $encoding = "gbk3";
                    break;
                } else {
                    $i += 3;
                }
            } else if ( ord($str[$i]) <= 251 ) { //前五位为11111
                if ( empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 or empty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 or empty($str[$i+4]) or  ord($str[$i+4]) >> 6 != 2) { //紧跟后两位为10
                    $encoding = "gbk4";
                    break;
                } else {
                    $i += 4;
                }
            } else if ( ord($str[$i]) <= 253 ) { //前六位为111111
                if ( empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 or empty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 or empty($str[$i+4]) or  ord($str[$i+4]) >> 6 != 2 or empty($str[$i+5]) or  ord($str[$i+5]) >> 6 != 2 ) { //紧跟后两位为10
                    $encoding = "gbk5";
                    break;
                } else {
                    $i += 5;
                }
            } else {
                $encoding = "gbk6";
                break;
            }
        }
    }
 
    if ($is_utf8_chinese == false){
        $encoding = "gbk10";
    }
    if ($encoding == "utf8" && preg_match("/^[".chr(0xa1)."-".chr(0xff)."\x20-\x7f]+$/", $str) && !preg_match("/^[\x{4e00}-\x{9fa5}\x20-\x7f]+$/u", $str)) {
        $encoding = "gbk7";
    }
    //echo $encoding;
    if ($encoding == "utf8") {
        //echo "utf8";
        return ($str == "鏈條" || $str == "瑷媄")? $str: mb_convert_encoding($str, "gbk", "utf8");
    } else {
        //echo "gbk";
        return $str;
    }
}

记得代码最好在gbk编码中运行,因为代码中有汉字($str == "鏈條" || $str == "瑷媄")比较。当然你可以在utf8编码中运行,只要把汉字处理下。


目录
相关文章
|
5月前
|
安全 API PHP
PHP中实现CORS跨域资源共享的方法
通过这种方式,你可以在PHP应用中灵活地实现CORS,以支持跨域Web应用的需求。
372 15
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
639 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
11月前
|
Ubuntu PHP Apache
在Ubuntu系统中为apt的apache2编译PHP 7.1的方法
以上就是在Ubuntu系统中为apt的apache2编译PHP 7.1的方法。希望这个指南能帮助你成功编译PHP 7.1,并在你的Apache服务器上运行PHP应用。
279 28
|
11月前
|
PHP 开发者
PHP数据验证方法:如何检查一个字符串是否是email格式。
以上就是关于PHP如何检查一个字符串是否是email格式的全部内容。希望你在代码书写旅途中,能找到你的北斗星——简洁、高效、可靠的代码验证方式。让我们共同见证PHP的强大和丰富多彩!
263 16
|
12月前
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
377 16
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
239 12
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
812 4
|
Java PHP 数据安全/隐私保护
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
本文详细介绍了PHP面向对象编程的一系列核心概念和用法,包括构造函数、析构函数、继承、方法重写、访问控制、接口、抽象类、静态成员、final关键字、以及this、self、parent这三个关键字的异同和作用。通过具体示例代码,展示了如何在PHP中使用这些面向对象的特性,以及它们在实际开发中的应用。
PHP 面向对象,构造函数,析构函数,继承,方法的重写,接口抽象类,static,final,this,parent,self的异同和作用
|
JSON 缓存 前端开发
PHP如何高效地处理JSON数据:从编码到解码
在现代Web开发中,JSON已成为数据交换的标准格式。本文探讨了PHP如何高效处理JSON数据,包括编码和解码的过程。通过简化数据结构、使用优化选项、缓存机制及合理设置解码参数等方法,可以显著提升JSON处理的性能,确保系统快速稳定运行。
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。