以前PHP/MYSQL的时候就耳闻过一些中文编码的问题,不过一直都是前后统一的Unicode编码,所以也没遇到太多问题。这次正式入职,公司MYSQL使用的是gb2312的字符集,因此在插入中文的时候也遇到了一些问题。
插入流程:
1、前台发起添加数据请求,数据中包含中文,编码为Unicode;
2、后台PHP脚本通过$_POST获得中文数据,接着直接插入到数据库中类型为text的字段;
插入结果:数据库中的字段显示的中文为乱码。
此时想当然的以为存储的字符串是以字节流形式保存,读取的时候根据编码转换就行
查询流程:
在数据库字段中文乱码的情况下,PHP脚本获得相关字段,此时直接输出页面依然为乱码;
结果:彻底推翻了插入流程时的想法。
为此做了一个简单的测试demo:
数据库:test, 数据表:test只包含一个类型为text的des字段
test.html页面代码如下:
<input
id="send"type="button"value="send"/>
<input
id="show"type="button"value="show"/>
<script>
document.getElementById('send').onclick=function(){
varxhr=
newXMLHttpRequest();
varparam=encodeURIComponent("啊啊啊");
xhr.open('post','test.php',true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send('des='+param);
};
document.getElementById('show').onclick=function(){
varxhr=
newXMLHttpRequest();
xhr.onload=function(){
alert(xhr.responseText);
}
xhr.open('post','test.php',true);
xhr.send(null);
};
</script>
send按钮用post方法提交数据,show按钮则查询数据。
test.php页面代码如下:
$db_host='127.0.0.1';
$user='root';
$pwd='';
$conn=mysql_connect($db_host,$user,$pwd);
$database=mysql_select_db('test',$conn);
if(isset($_POST['des'])){
$sql="INSERT
INTO `test` VALUES ('$_POST[des]')";
$query=mysql_query($sql);
}else{
$sql="select
* from `test`";
$query=mysql_query($sql);
$result=mysql_fetch_array($query);
echo$result[0];
}
也就是根据请求字段判断是插入操作还是查询操作。
对应前面描述的插入流程与查询流程。
解决方案:
在操作数据前加入一句:mysql_set_charset('gb2312');
同时用iconv将字符串转为gb2312编码。
这样数据库的字段就正常了~~,同时查询出来的中文字段也正常了~
不过具体原理有待搞明白。
上面只是主要问题中的一个,接下来的问题则是json_encode的问题:
由于取出的字符串编码不是Unicode,而json_encode只能对Unicode进行编码,因此对于非Unicode字符串,只会编码为null。
因此还需要用iconv将字符串转为utf8编码,才能用json_encode。