Heim >php教程 >php手册 >About字符编码

About字符编码

WBOY
WBOYOriginal
2016-06-06 20:12:371814Durchsuche

打开"记事本"程序Notepad.exe,新建一个文本文件,内容就是一个"严"字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。 然后,用文本编辑软件UltraEdit中的"十六进制功能",观察该文件的内部编码方式。 1)ANSI:文件的编码就是两个字节

打开"记事本"程序Notepad.exe,新建一个文本文件,内容就是一个"严"字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。

然后,用文本编辑软件UltraEdit中的"十六进制功能",观察该文件的内部编码方式。

1)ANSI:文件的编码就是两个字节"D1 CF",这正是"严"的GB2312编码,这也暗示GB2312是采用大头方式存储的。

2)Unicode:编码是四个字节"FF FE 25 4E",其中"FF FE"表明是小头方式存储,真正的编码是4E25。

3)Unicode big endian:编码是四个字节"FE FF 4E 25",其中"FE FF"表明是大头方式存储。

4)UTF-8:编码是六个字节"EF BB BF E4 B8 A5",前三个字节"EF BB BF"表示这是UTF-8编码,后三个"E4B8A5"就是"严"的具体编码,它的存储顺序与编码顺序是一致的。

UTF-8编码的文件中,BOM占三个字节。如果用记事本把一个文本文件另存为UTF-8编码方式的话,用UE打开这个文件,切换到十六进制编辑状态就可以看到开头的FFFE了。这是个标识UTF-8编码文件的好办法,软件通过BOM来识别这个文件是否是UTF-8编码,很多软件还要求读入的文件必须带BOM。可是,还是有很多软件不能识别BOM。

PHP在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头BOM的那三个字符。

由于必须在在Bo-Blog的wiki看到,同样使用PHP的Bo-Blog也一样受到BOM的困扰。其中有提到另一个麻烦:“受COOKIE送出机制的限制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效。一切依赖COOKIE、SESSION实现的功能全部无效。”这个应该就是Wordpress后台出现空白页面的原因了,因为任何一个被执行的文件包含了BOM,这三个字符都将被送出,导致依赖cookies和session的功能失效。

解决的办法嘛,如果只包含英文字符(或者说ASCII编码内的字符),就把文件存成ASCII码方式吧。用UE等编辑器的话,点文件->转换->UTF-8转ASCII,或者在另存为里选择ASCII编码。如果是DOS格式的行尾符,可以用记事本打开,点另存为,选ASCII编码。如果包含中文字符的话,可以用UE的另存为功能,选择“UTF-8 无 BOM”即可。

当然在Python程序中处理的时候遇到这种情况改怎么处理呢?

方法一:直接将源文件的格式修改一下,将其保存为UTF-8即可,但是很多时候传过来的源文件是没法修改的,这样就行不通了。

方法二:替换,就是将其中的\xef\xbb\xbf替换为空就可以了。

VIM 十六进制和文本模式切换

使用vim打开文件后,使用命令

:%!xxd 使用十六进制显示;
:%!xxd -r 返回文本显示。

只有十六进制部分的修改才会被采用。右边可打印文本部分的修改忽略不计。

vim以二进制打开文件

vim -b binfile

在 Vim 中将文件保为无 BOM 的 UTF-8 格式

查看文件格式

通常我们需要先查看文件格式是否与预期的一样,再根据结果决定是否需要修改(当然你也可以在不知道原格式的情况下直接修改),下面分别给出了查看文件编码和是否带有 BOM 的命令。

# 查看文件编码。
set fenc?
# 查看是否带 BOM。
set bomb?

修改文件格式

# 设置为 UTF-8 编码。
set fenc=utf-8
# 设置为无 BOM,如需设置为带 BOM 则使用 "set bomb"。
set nobomb
# 加上BOM标记
set bomb

使用linux命令删除UTF-8编码中的BOM

shell> grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//;q'
or
shell> grep -r -I -l $'^\xEF\xBB\xBF' /path | xargs sed -i 's/^\xEF\xBB\xBF//g'
or
shell> tail -c +4 old_file > new_file

如果使用SVN提交代码的话,可以在pre-commit钩子里加上相关代码用以杜绝BOM。

#!/bin/bash
REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook
for FILE in $($SVNLOOK changed -t "$TXN" "$REPOS" | awk '/^[AU]/ {print $NF}'); do
    if $SVNLOOK cat -t "$TXN" "$REPOS" "$FILE" | grep -q $'^\xEF\xBB\xBF'; then
        echo "Byte Order Mark be found in $FILE" 1>&2
        exit 1
    fi
done

不含 BOM 的 UTF-8 才是标准形式!
带 BOM 的 UTF-8 就是赤裸裸的流氓!!!

不同编码的BOM表示

编码 十六进制表示
UTF-8 EF BB BF
UTF-16-BE FE FF
UTF-16-LE FF FE
UTF-32-BE 00 00 FE FF
UTF-32-LE FF FE 00 00
UTF-7 2B 2F 76和以下的一个字节:[ 38 39 2B 2F ]
en:UTF-1 F7 64 4C
en:UTF-EBCIC DD 73 66 73
en:Standard Compression Scheme for Unicode 0E FE FF
en:BOCU-1 FB EE 28及可能跟随着FF
GB-18030 84 31 95 33

vim 将文件从dos格式转换到unix格式

:set fileformat=unix
:w

VIM 状态栏显示 文件格式带bom
Show fileencoding and bomb in the status line

http://vim.wikia.com/wiki/Show_fileencoding_and_bomb_in_the_status_line

比如 [latin1], [iso-8859-15], [utf-8,B], etc.

if has("statusline")
 set statusline=%
<p>其实有用的就是这段:</p>
<pre class="brush:php;toolbar:false">
%{\"[\".(&fenc==\"\"?&enc:&fenc).((exists(\"+bomb\")\ &&\ &bomb)?\",B\":\"\").\"]\ \"}
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn