• mysql字符集编码乱码测试如下


    创建三个表tb_latin1,tb_utf8,tb_gbk,编码分别为latin1/utf8/gbk

    “你好a”字符串编码如下
    GBK : %C4%E3 %BA%C3 %61
    UTF-8 : %E4%BD%A0 %E5%A5%BD %61

    测试代码如下

    <?php
    //fileencoding=gb2312
    mysql_query("set names gbk");
    mysql_query("insert into test.tb_latin values('gbk', '你好a')");
    /*
        连接的字符集是GBK,一个字符由一到两个字节表示,传入 %C4%E3 %BA%C3 %61
        存储的字符集是latin1,一个字符由一个字节表示
    
        mysql将传入的三个字符转换为latin1的三个字符变成 %3F(找不到对应的转换对应表表) %3F %61
    
        导致数据存储错误(??a) (存储占用3字节)
    */
    mysql_query("insert into test.tb_utf8 values('gbk', '你好a')");
    /*
        连接的字符集是GBK,一个字符由一到两个字节表示,传入 %C4%E3 %BA%C3 %61
        存储的字符集是utf8,一个字符由一到四个字节表示
    
        mysql将传入的三个字符转换为utf8的三个字符变成 %E4%BD%A0 %E5%A5%BD %61(存储占用7字节)
    
        读取时连接设置为UTF-8和GB2312都可以,但指定为latin1会出现转码失败返回错误内容(??a)
        UTF-8返回7字节,GB2312返回5字节
    */
    mysql_query("insert into test.tb_gbk values('gbk', '你好a')");
    /*
        连接的字符集是GBK,一个字符由一到两个字节表示,传入 %C4%E3 %BA%C3 %61
        存储的字符集是GBK,保存为 %C4%E3 %BA%C3 %61 存储占用5字节
    
        读取时连接设置为UTF-8和GB2312都可以,但指定为latin1会出现转码失败返回错误内容(??a)
        UTF-8返回7字节,GB2312返回5字节 
    */
    ?>
    <?php
    //fileencoding=gb2312
    mysql_query("set names latin1");
    mysql_query("insert into test.tb_latin values('gblatin1', '你好a')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %C4 %E3 %BA %C3 %61
        存储的字符集是latin1,一个字符由一到四个字节表示,存储为 %C4 %E3 %BA %C3 %61 (存储占用5字节)
    
        读取时连接编码为latin1,前端获取五个字符(%C4 %E3 %BA %C3 %61)
            如果vim(term)环境如果正好是gb2312编码环境则显示文本“你好a”
            如果vim(term)显示环境编码为latin1,显示(乱码)
            如果vim(term)语言环境为utf8,转码(由latin1转UTF8)会失败显示(???a)
        读取时连接为gbk,mysql无法将五个字符转成5个相应的gbk编码,返回(????a)错误内容
        读取时连接为utf8,mysql将五个字符转换为 %C3%84 %C3%A3 %C2%BA %C3%83 %61 错误内容,具体呈现看term编码
    */
    mysql_query("insert into test.tb_utf8 values('gblatin1', '你好a')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %C4 %E3 %BA %C3 %61
        存储的字符集是utf8,一个字符由一个字节表示,存储为 %C3%84 %C3%A3 %C2%BA %C3%83 %61 (存储占用5字节)
    
        读取时连接编码为latin1,前端获取五个字符(%C4 %E3 %BA %C3 %61) (mysql把错误的编码转为latin1)
            如果vim(term)环境如果正好是gb2312编码环境则显示文本“你好a”
            如果vim(term)显示环境编码为latin1,显示(乱码)
            如果vim(term)语言环境为utf8,转码(由latin1转UTF8)会失败显示(???a)
        读取时连接为gbk,mysql无法将五个字符转成5个相应的gbk编码,返回(????a)错误内容
        读取时连接为utf8,mysql将五个字符转换为 %C3%84 %C3%A3 %C2%BA %C3%83 %61 错误内容,具体呈现看term编码
    */
    mysql_query("insert into test.tb_gbk values('gblatin1', '你好a')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %C4 %E3 %BA %C3 %61
        存储的字符集是gbk,一个字符由一到两个字节表示,mysql无法将五个字符转成5个相应的gbk编码,存储(????a)错误内容
    */
    ?>
    <?php
    //fileencoding=utf8
    mysql_query("set names utf8");
    mysql_query("insert into test.tb_latin1 values('utf8', '你好')");
    /*
        连接的字符集是UTF-8,一个字符由一到四个字节表示,传入 %E4%BD%A0 %E5%A5%BD %61
        存储的字符集是latin1,一个字符由一个字节表示
    
        mysql将传入的三个字符转换为latin1的三个字符变成 %3F(找不到对应的转换对应表表) %3F %61
    
        导致数据存储错误(??a) (存储占用3字节)
    */
    mysql_query("insert into test.tb_utf8 values('utf8', '你好')");
    /*
        连接的字符集是UTF-8,一个字符由一到四个字节表示,传入 %E4%BD%A0 %E5%A5%BD %61
        存储的字符集是utf8,一个字符由一到四个字节表示,存储 %E4%BD%A0 %E5%A5%BD %61
    
        读取时连接设置为UTF-8和GB2312都可以,但指定为latin1会出现转码失败返回错误内容(??a)
        UTF-8返回7字节,GB2312返回5字节
    */
    mysql_query("insert into test.tb_gbk values('utf8', '你好')");
    /*
        连接的字符集是UTF-8,一个字符由一到四个字节表示,传入 %E4%BD%A0 %E5%A5%BD %61
        存储的字符集是GBK,保存为 %C4%E3 %BA%C3 %61 存储占用5字节
    
        读取时连接设置为UTF-8和GB2312都可以,但指定为latin1会出现转码失败返回错误内容(??a)
        UTF-8返回7字节,GB2312返回5字节 
    */
    ?>
    <?php
    //fileencoding=utf8
    mysql_query("set names latin1");
    mysql_query("insert into test.tb_latin values('latin1', '你好')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %E4 %BD %A0 %E5 %A5 %BD %61
        存储的字符集是latin1,一个字符由一个字节表示,存储为 %E4 %BD %A0 %E5 %A5 %BD %61 (存储占用7字节)
    
        读取时连接编码为latin1,前端获取七个字符(%E4 %BD %A0 %E5 %A5 %BD %61)
            如果vim(term)环境如果正好是UTF8编码环境则显示文本“你好a”
            如果vim(term)显示环境编码为latin1,显示(乱码)
            如果vim(term)语言环境为gbk,乱码
        读取时连接为gbk,mysql无法将七个字符转成对应的七个相应的gbk编码,返回(??????a)错误内容
        读取时连接为utf8,mysql将七个字符转换为 %c3%a4 %c2%bd %c2%a0 %c3%a5 %c2%a5 %c2%bd %61 内容返回(显示错误)
    */
    mysql_query("insert into test.tb_utf8 values('latin1', '你好')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %E4 %BD %A0 %E5 %A5 %BD %61
        存储的字符集是utf8,一个字符由一个到四个字节表示,存储为 %c3%a4 %c2%bd %c2%a0 %c3%a5 %c2%a5 %c2%bd %61 (存储占用13字节,业务侧需转为latin1方可显示正确内容)
    
        读取时连接编码为latin1,前端获取五个字符(%E4 %BD %A0 %E5 %A5 %BD %61) (mysql把13个字节的7个字符转为latin1)
            如果vim(term)环境如果正好是utf8编码环境则显示文本“你好a”
            如果vim(term)显示环境编码为latin1,显示(乱码)
            如果vim(term)语言环境为gbk,乱码
        读取时连接为gbk,mysql无法将7个字符转成7个相应的gbk编码,返回(??????a)错误内容
        读取时连接为utf8,mysql将五个字符转换为 %c3%a4 %c2%bd %c2%a0 %c3%a5 %c2%a5 %c2%bd %61 错误内容,具体呈现看term编码
    */
    mysql_query("insert into test.tb_gbk values('latin1', '你好')");
    /*
        连接的字符集是latin1,一个字符由一个字节表示,传入 %E4 %BD %A0 %E5 %A5 %BD %61
        存储的字符集是gbk,一个字符由一到两个字节表示,mysql无法将7个字符转成7个相应的gbk编码,存储(??????a)错误内容
    */
    ?>

    数据库查询如下

    mysql> select charset, data,length(data) from tb_latin;
    +----------+---------+--------------+
    | charset  | data    | length(data) |
    +----------+---------+--------------+
    | gbk      | ??a     |            3 |
    | gblatin1 | ????a   |            5 |
    | utf8     | ??a     |            3 |
    | latin1   | ??????a |            7 |
    +----------+---------+--------------+
    4 rows in set (0.00 sec)
    
    mysql> select charset, data,length(data) from tb_utf8;
    +----------+---------+--------------+
    | charset  | data    | length(data) |
    +----------+---------+--------------+
    | gbk      | ???a   |            7 |
    | gblatin1 | ????a   |            9 |
    | utf8     | ???a   |            7 |
    | latin1   | ??????a |           13 |
    +----------+---------+--------------+
    4 rows in set (0.00 sec)
    
    mysql> select charset, data,length(data) from tb_gbk;
    +----------+---------+--------------+
    | charset  | data    | length(data) |
    +----------+---------+--------------+
    | gbk      | ???a   |            5 |
    | gblatin1 | ????a   |            5 |
    | utf8     | ???a   |            5 |
    | latin1   | ??????a |            7 |
    +----------+---------+--------------+

    附测试代码如下:

    <?php
    //...
    mysql_query("set names latin1");
    $result=mysql_query("SELECT * FROM test.tb_gbk where charset='latin1'");
    while($row=mysql_fetch_row($result))
    {
    var_dump($row);
    echo bin2hex($row[1]);
    }
    ?>
    <?php
    
    $a="%c3%a4%c2%bd%c2%a0%c3%a5%c2%a5%c2%bd%61";
    $b = urldecode($a);
    var_dump(bin2hex($b));
    $c = iconv("UTF-8","latin1",$b);
    var_dump(bin2hex($c));
    
    ?>
  • 相关阅读:
    教师派10
    教师派9
    简单理解socket(AF_INET&SOCK_STREAM,SOCK_DGRAM)
    Deepin安装MySQL(MariaDB)不提示设置密码问题(密码为空)
    经典排序算法-附python代码
    Linux虚拟环境virtualevn
    linux安装虚拟环境
    deepin安装虚拟环境virtualenv
    deepin安装虚拟环境virtualenv
    把握AFNet网络请求完成的正确时机
  • 原文地址:https://www.cnblogs.com/ciaos/p/4889346.html
Copyright © 2020-2023  润新知