PHP自动判断字符集并转码

直接check utf-8的BOM信息
服务器君一共花费了127.890 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

原理很简单,因为gb2312/gbk是中文两字节,这两个字节是有取值范围的,而utf-8中汉字是三字节,同样每个字节也有取值范围。而英文不 管在何种编码情况下,都是小于128,只占用一个字节(全角除外)。

如果是文件形式的编码检查,还可以直接check utf-8的BOM信息。话不多说,直接上函数,这个函数是用来对字符串进行检查和转码的。

<?php
function safeEncoding($string,$outEncoding ='UTF-8')    
{    
	$encoding = "UTF-8";    
	for($i=0;$i<strlen($string);$i++)    
	{    
		if(ord($string{$i})<128)    
      		continue;    
        
		if((ord($string{$i})&224)==224)    
		{    
  			//第一个字节判断通过    
     		$char = $string{++$i};    
  			if((ord($char)&128)==128)    
     		{    
           		//第二个字节判断通过    
         		$char = $string{++$i};    
            	if((ord($char)&128)==128)    
         		{    
              		$encoding = "UTF-8";    
              		break;    
         		}    
       		}    
 		}    
	
		if((ord($string{$i})&192)==192)    
      	{    
          	//第一个字节判断通过    
         	$char = $string{++$i};    
        	if((ord($char)&128)==128)    
          	{    
          		// 第二个字节判断通过    
               	$encoding = "GB2312";    
				break;    
			}    
     	}    
	}    
             
	if(strtoupper($encoding) == strtoupper($outEncoding))    
		return $string;    
	else   
       	return iconv($encoding,$outEncoding,$string);    
}
?>

关于BOM

字节顺序记号(英:byte-order mark,BOM)是位于码点 U+FEFF 的统一码字符("零宽度无断空白")。当以 UTF-16 或 UTF-32 来将UCS/统一码字符所组成的字串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以 UTF-8 、 UTF-16 或 UTF-32 编码的记号。

在大部分的字符编码中,字节顺序记号是一个不太可能出现在其它文件的样式(它通常看起来像是一个混淆的控制码的序列)。如果字节顺序记号被误解成统一码文件中真正的字符时,那么它将不可视,因为它是零宽度无断空白。在 Unicode3.2 中, U+FEFF 用于非字节顺序记号的用途已被舍弃(取而代之的是,使用 U+2060 来表示这种用途),以容许 U+FEFF 仅被地用于字节顺序记号的语意。

在 UTF-16 中,字节顺序记号被放置为档案或字符串流的第一个字符,以标示在此档案或字符串流中,以所有十六位元为单位的字码的尾序(字节顺序)。

  • 如果十六位元单位被表示成大尾序,这字节顺序记号字符在序列中将呈现 0xFE ,其后跟着 0xFF(其中的 0x 用来标示十六进制)。
  • 如果十六位元单位使用小尾序,这个字节序列为 0xFF ,其后接着0xFE。

而统一码中,值为U+FFFE 的码位被保证将不会被指定成一个统一码字符。这意味着 0xFF 、 0xFE 将只能被解释成小尾序中的U+FEFF(因为不可能是大尾序中的 U+FFFE )。

UTF-8 则没有字节顺序的议题。UTF-8编码过的字节顺序记号则被用来标示它是 UTF-8 的文件。它只用来标示一个 UTF-8 的档案,而不用来说明字节顺序。[1] 许多 视窗 程式(包含记事本)会添加字节顺序记号到 UTF-8 档案。然而,在 类Unix系统 系统(大量使用 en:text file ,用于 档案格式 ,用于行程间通讯)中,这种作法则不被建议采用。因为它会妨碍到如解译器脚本开头的 en:Shebang 等的一些重要的码的正确处理。它亦会影响到无法识别它的编程语言。如 gcc 会报告源码档开头有无法识别的字符。而在 PHP 中,如果没有启用输出缓冲(output buffering),它会使得页面内容开始被送往浏览器(即:用户标头档已被送出),这使 PHP 脚本无法指定用户标头档(HTTP Header)。字节顺序记号在 UTF-8 中被表示为序列 EF BB BF,对大部分未准备好处理 UTF-8 的 文本编辑器 及 网页浏览器 而言,在 ISO-8859-1 的环境中则会显示 ??? 。

虽然字节顺序记号亦可以用于 UTF-32 ,但这个编码很少用于传输,其规则如同 UTF-16 。对于已于IANA注册的字符集 UTF-16BE、UTF-16LE 、 UTF-32BE 和 UTF-32LE 等来说,不可使用字节顺序记号。文档开头的 U+FEFF 会被解释成一个(已舍弃的)"零宽度无断空白",因为这些字符集的名字已决定了其字节顺序。对于已注册字符集 UTF-16 和 UTF-32 来说,一个开头的 U+FEFF 则用来表示字节顺序。

本文地址:http://www.nowamagic.net/librarys/veda/detail/952,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/952

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《编程之美:微软技术面试心得》 《编程之美》小组 (作者)

《编程之美:微软技术面试心得》是一本让人着迷的书!阅读起来。有些题目的内容会引起强烈的共鸣,尤其是那些自己非常熟悉并且又深知解答的题目;也有一些题目让我异常惊诧,原来除了我所知道的解答思路之外,还有更好的解答以及更深层次的原因。还有一些题目是从来没想到过的。阅读过程是一次愉快的享受,也是脑细胞持续活跃的过程。

更多计算机宝库...