PHP存取 Mysql 数据乱码终极解决方案

来源:互联网 发布:mac雷电转usb 编辑:程序博客网 时间:2024/03/29 14:21
对PHP和Mysql 的研究并不深入,以下是我的一些个人心得,说的可能不是很明白,但确实是很管用的东西,
我的Discuz版本是UTF-8的,但是打开phpmyadmin显示的是 整理栏目:gbk_chinese_ci ,而且查看数据显示完全正常,没有乱码,这个表示,实际 discuz在存取数据库用的是 gbk编码,但页面显示确实UTF-8编码阿,怎么没有乱码呢?难道Discuz做了编码转换?
  最近在公司开发一个网站,由于用到了 cakephp框架 ,默认编码为UTF-8,而且我的计算机是Ubuntu,通常用的都是UTF-8编码,所写的程序页面也都是UTF-8编码的文件,自然想到用UTF-8编码的数据库,这个问题可把我苦大了
按照一般网上的说法是建立数据库表的时候加上  DEFAULT CHARSET UTF8 ,创建的表的整理栏目在phpmyadmin里面显示的 是
utf8_general_ci ,在执行sql 语句是加上“set names utf8”,这样就会正常了,插入的数据在页面里面显示完全正常,我的页面是 设置了UTF-8编码的 ,
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> ,按理说应该没有什么问题的,
但是在Phpmyadmin里面显示的确是乱码,而且如果我在phpmyadmin里面修改了一个数据,
在phpmyadmin里面显示就是正常了,但是到页面显示却乱码了,
于是我想参考一下discuz的做法在phpmyadmin里面强行把表和所有的char,varchar 和 text 字段改为gbk_chinese_ci
,修改后,phpmyadmin 里面正常了,但是到页面显示确是乱码了,公司原来的数据库是 ms-sql server 2000 的现在要导入到 mysql5,
原来的 两个汉字在导入到 char(10)的时候 竟然报错说是字符太长了,怎么可能呢?一个字符按照UTF16也就4个字节 最多才到8个字节阿
怎么回事阿?网上有人说是由于编码不当可能会把UTF8的编码经过两次转换 变成一个汉字6个字节存储,具体是怎么回事我也不清楚
,不过后来经过多次实验终于明白了原来Mysql存取编码和查询编码并不一致,需要手动指定,也可以在 mysql 的配置文件里指定编码
网上有人的解决办法是:
PHP源文件使用的是UTF-8编码 mysql 存储用的是GBK编码
set character_set_client = utf8;
指明也即php程序发往数据库的SQL语句使用的是UTF8编码,如insert;
set character_set_connection = GBK;
指明数据库收到SQL语句之后应当将其从character_set_client转码为
utf8格式进行操作,如insert。(若没有这一句,插入的数据将变成问号)
set character_set_results = utf8;
指明数据库查询完毕之后应当以何种编码返回给调用端,如select。

现在终极解决办法,
php 文件为UTF-8时的做法:
在所有执行mysql_query函数做数据库插入删除查询之前 执行下面三个命令:
mysql_query('set character_set_client = utf8');
mysql_query('set character_set_connection = GBK');
mysql_query('set character_set_results = utf8');
而不是以前的 set names utf8命令
创建数据库和创建表之时指定编码为gbk ,指定 整理为 gbk_chinese_ci;
CREATE DATABASE `test` DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;

这样你的网站永远 都不会有乱码问题了
而且如果有一个字段是 username char(20),
这样就可以插入20个汉字,而不是20/2或者 20/3之类
如果插入的是20个汉字, select length(username)查看 会返回 40 ,也就是说,mysql 实际是用40个字符存储的
但是我们不用去管他实际的存储,你想要限制多少就直接是指定char()多少就可以了,汉字和英文同样对待。

原创粉丝点击