编码问题 php字符编码转换类
各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求。
php 字符编码转换类,支持ANSI、Unicode、Unicode big endian、UTF-8、UTF-8+Bom 互相转换。
四种常见文本文件编码方式
ANSI编码:
无文件头(文件编码开头标志性字节)
ANSI编码字母数字占一个字节,汉字占两个字节
回车换行符,单字节, 十六进制表示为0d 0a
UNICODE编码:
文件头,十六进制表示为FF FE
每一个字符都用两个字节编码
回车换行符, 双字节,十六进制表示为 000d 000a
Unicode big endian编码:
文件头十六进制表示为FE FF
后面编码是把字符的高位放在前面,低位放在后面,正好和Unicode编码颠倒
回车换行符,双字节,十六进制表示为0d00 0a00
UTF-8 编码:
文件头,十六进制表示为EF BB BF
UTF-8是Unicode的一种变长字符编码,数字、字母、回车、换行都用一个字节表示,汉字占3个字节
回车换行符,单字节,十六进制表示为0d 0a
转换原理:先把字符编码转为UTF-8,然后再从UTF-8转换为对应的字符编码。
CharsetConv.class.php:
1 <?php 2 /**字符编码转换类, ANSI、Unicode、Unicode big endian、UTF-8、UTF-8+Bom互相转换 3 *Date: 2015-01-28 4 *Author: fdipzone 5 *Ver: 1.0 6 * 7 *Func: 8 *public convert 转换 9 *private convToUtf8 把编码转为UTF-8编码 10 *private convFromUtf8 把UTF-8编码转换为输出编码 11 */ 12 13 class CharsetConv{ // class start 14 15 private $_in_charset = null; // 源编码 16 private $_out_charset = null; // 输出编码 17 private $_allow_charset = array('utf-8', 'utf-8bom', 'ansi', 'unicode', 'unicodebe'); 18 19 /**初始化 20 * @param String $in_charset 源编码 21 * @param String $out_charset 输出编码 22 */ 23 public function __construct($in_charset, $out_charset){ 24 25 $in_charset = strtolower($in_charset); 26 $out_charset = strtolower($out_charset); 27 28 // 检查源编码 29 if(in_array($in_charset, $this->_allow_charset)){ 30 $this->_in_charset = $in_charset; 31 } 32 33 // 检查输出编码 34 if(in_array($out_charset, $this->_allow_charset)){ 35 $this->_out_charset = $out_charset; 36 } 37 38 } 39 40 /**转换 41 * @param String $str 要转换的字符串 42 * @return String 转换后的字符串 43 */ 44 public function convert($str){ 45 46 $str = $this->convToUtf8($str); // 先转为utf8 47 $str = $this->convFromUtf8($str); // 从utf8转为对应的编码 48 49 return $str; 50 } 51 52 /**把编码转为UTF-8编码 53 * @param String $str 54 * @return String 55 */ 56 private function convToUtf8($str){ 57 58 if($this->_in_charset=='utf-8'){ // 编码已经是utf-8,不用转 59 return $str; 60 } 61 62 switch($this->_in_charset){ 63 case 'utf-8bom': 64 $str = substr($str, 3); 65 break; 66 67 case 'ansi': 68 $str = iconv('GBK', 'UTF-8//IGNORE', $str); 69 break; 70 71 case 'unicode': 72 $str = iconv('UTF-16le', 'UTF-8//IGNORE', substr($str, 2)); 73 break; 74 75 case 'unicodebe': 76 $str = iconv('UTF-16be', 'UTF-8//IGNORE', substr($str, 2)); 77 break; 78 79 default: 80 break; 81 } 82 83 return $str; 84 85 } 86 87 /**把UTF-8编码转换为输出编码 88 * @param String $str 89 * @return String 90 */ 91 private function convFromUtf8($str){ 92 93 if($this->_out_charset=='utf-8'){ // 输出编码已经是utf-8,不用转 94 return $str; 95 } 96 97 switch($this->_out_charset){ 98 case 'utf-8bom': 99 $str = "\xef\xbb\xbf".$str; 100 break; 101 102 case 'ansi': 103 $str = iconv('UTF-8', 'GBK//IGNORE', $str); 104 break; 105 106 case 'unicode': 107 $str = "\xff\xfe".iconv('UTF-8', 'UTF-16le//IGNORE', $str); 108 break; 109 110 case 'unicodebe': 111 $str = "\xfe\xff".iconv('UTF-8', 'UTF-16be//IGNORE', $str); 112 break; 113 114 default: 115 break; 116 } 117 118 return $str; 119 120 } 121 122 } // class end 123 124 ?>
demo:unicode big endian 转为 utf-8+bom:
1 <?php 2 require "CharsetConv.class.php"; 3 4 $str = file_get_contents('source/unicodebe.txt'); 5 6 $obj = new CharsetConv('unicodebe', 'utf-8bom'); 7 $response = $obj->convert($str); 8 9 file_put_contents('response/utf-8bom.txt', $response, true); 10 ?>