原创文章,转载请注明: 转载自电商沙龙ec-shalom.com,专研电商艺术。
本文链接地址: 字符编码与字符集区别与联系(网页/PHP文件/MYSQL数据库乱码问题)
一直对网页编码、字符集的概念模糊不清,今天总算是抽出了时间好好对这个问题进行了深入的研究。
1. 相关定义:
- 抽象字符集:指字符的集合,例如所有的英文字母是一个抽象字符集,所有的汉字是一个抽象字符集,当然,把全世界所有语言的符号都放在一起,也可以称为一个抽象字符集。
- 编码 字符集 ( 互动百科 | 维基百科 ):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
- 字符编码 ( 互动百科 | 维基百科 ):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如号码或电脉冲)进行配对。即在符号集合与数字 系统 之间建立对应关系,它是信息处理的一项基本技术。通常人们用符号集合(一般情况下就是文字)来表达信息。而以计算机为基础的信息处理系统则是利用元件(硬 件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字 代码。
- bom全称是: byte order mark ( 互动百科 | 维基百科 ),汉语意思是标记字节顺序码。只是出现在:unicode字符集中,只有unicode字符集,存储时候,要求指定编码,如果不指定,windows还会用默认的:ANSI读取。
2. 网页要在浏览器中正确显示,需要在三个地方保持编码的一致:网页文件,网页编码声明和浏览器编码设置。 网页文件本身的编码,即网页文件在被创建的时候使用什么编码来保存。这个完全取决于创建该网页的人员使用了什么编码保存,而进一步的取决于该人员使用的操 作系统。例如我们使用的中文版WindowsXP系统,当你新建一个文本文件,写入一些内容,并按下ctrl+s进行保存的那一刻,操作系统就替你使用 GBK编码将文件进行了保存(没有使用UTF-8,也没有使用UTF-16)。而使用了英文系统的人,系统会使用ISO-8859-1进行保存,这也意味 着,在英文系统的文件中如果输入一个汉字,是无法进行保存的。 在创建XML文件时常见的误解是以为只要在页面的encoding部分声明了UTF-8,则文件就会被保存为 UTF-8格式。实际上XML文件中encoding部分与HTML文件中的charset中一样,只是告诉“别人” (这个“别人”可能是浏览你的页面的人,也可能是浏览器,还可能是处理你页面的程序,别人需要知道这个,因为除非你告诉他们,否则谁也猜不出你用了什么编码,仅通过文件的内容判断不出使用了什么编码。) 这 个文件使用了什么编码,唯独操作系统不会搭理,它仍然会按自己默认的编码方式保存文件(中文WindowsXP系统中,使用GBK保存)。至于这个文件是 不是真的是encoding或者charset所声明的那种编码保存的呢?答案是不一定!例如新浪的页面就“声称”他是用GB2312编码保存的,但实际 上却是GBK。
网页编码声明中的编码应该与网页文件保存时使用的编码一致。 而浏览器的编码设置实际上并不严格,在浏览器中选择使用 GB2312来查看,它实际上仍然会使用GBK进行。而且浏览器还有这样一种好习惯,即它会尽量猜测使用什么编码查看最合适。要重申的是,网页文件的编 码和网页文件中声明的编码保持一致,这是一个极好的建议,但如果不一致,只要网页文件的编码与浏览器的编码设置一致, 也是可以正确显示的。例如有这样一个页面,它使用GBK保存,但声明自己是UTF-8的。这个时候用浏览器打开它,首先会看到乱码,因为这个页面“告诉” 浏览器用UTF-8显示,浏览器会很尊重这个提示,于是乱码一片。但当手工把浏览器设为GBK之后,显示正常。
3.bom头产生网页乱码, 有bom头的存储或者字节流,它一定是unicode字符集编码。到底属于那一种(utf-8还是utf-16或是utf-32),通过头可以判断出来。 由于已经说过utf-16,utf-32不指定bom头,解析程序默认就认为是ansi编码,出现乱码。 而utf-8指定或者不指定程序都可判断知道对于的字符集编码。问题就出在这里,可能有的应用程序(ie6浏览器),它就认为如果utf-8编码,就不需 要指定bom头,它可以自己判断,相反指定了bom头,它还会出现问题(因为它把头当utf-8解析出现乱码了)。目前ie6会出现问题,其它 ie7+,firefox,chrome不会出现,会忽略掉bom头。 统一解决办法是:存为utf-8编码是,不需要加入bom头,其它utf-16,utf-32加入。
4. PHP文件编码问题,点击编辑器的菜单:“文件”->“另存为”,确保文件编码为:UTF-8,如果是ANSI,需要将编码改成:UTF-8
PHP文件头BOM问题:
PHP文件一定不可以有BOM标签 ,否则,会出现session不能使用的情况,并有类似的提示:
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent
这是因为,在执行session_start() 的时候,整个页面不能有输出,但是当由于前PHP页面存在BOM标签,PHP把这个BOM标签当成是输出了,所以就出错了!所以PHP页面一定要删除 BOM标签,删除这个BOM标签的方法: 1.可以用Dreamweaver打开文件,并重新保存,即可以去除BOM标签! 2.可以用EditPlus打开文件,并在菜单“首选项”->“文件”->"UTF-8标识",设置为:“总是删除签名”, 然后保存文件,即可以去除BOM标签! 3.PHP以附件形式保存文件的时候,UTF-8编码问题: PHP以附件形式保存文件,文件名必须是GB2312编码, 否则,如果文件名中有中文的话,将是显示乱码: 如果你的PHP本身是UTF-8编码格式的文件, 需要将文件名变量由UTF-8转成GB2312: iconv("UTF-8", "GB2312", "$filename");
5.MYSQL数据库使用UTF-8编码的问题,
用phpmyadmin创建数据库和数据表 :创建数据库的时候,请将“整理”设置为:“utf8_general_ci” 或执行语句:
CREATE DATABASE `dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
创建数据表的时候:如果是该字段是存放中文的话,则需要将“整理”设置为:“utf8_general_ci”,如果该字段是存放英文或数字的话,默认就可以了。相应的SQL语句,例如:
CREATE TABLE `test` ( `id` INT NOT NULL , `name` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , PRIMARY KEY ( `id` ) ) ENGINE = MYISAM ;
用PHP读写数据库:在连接数据库之后,
$connection = mysql_connect($host_name, $host_user, $host_pass);
加入两行:
mysql_query("set character set 'utf8'");//读库 mysql_query("set names 'utf8'");//写库
就可以正常的读写MYSQL数据库了。
6.PHP自动识别字符集并完成转码函数以及PHP - 判断utf-8编码是否存在BOM并自动删除: (略)。
7.扩展阅读:《字符编码笔记:ASCII,Unicode和UTF-8》