utf8_encode函数的作用是什么?

7

假设我正在使用UTF-8编码我的文件。

在PHP脚本中,将比较一个字符串:

$string="ぁ";
$string = utf8_encode($string); //Do i need this step?
if(preg_match('/ぁ/u',$string))
//Do if match...

如果您使用UTF-8编码,那么是否真的需要utf8_encode()函数对字符串进行编码呢?


是的,但如果我使用UTF-8编码我的文件,这仍然是必要的吗?我的意思是它们已经以UTF-8编码,为什么还要再次编码呢? - nEAnnam
4个回答

11
如果你查阅 utf8_encode 的手册条目,它会将一个ISO-8859-1编码的字符串转换为UTF-8。函数名是一个非常糟糕的误导,因为它暗示了一些必要的自动编码。但实际上不是这样的情况。如果你的源代码已经保存为UTF-8,并且你将 "あ" 赋值给$string,那么$string将持有以UTF-8编码的字符 "あ"。不需要进行进一步的操作。实际上,试图(错误地)从ISO-8859-1转换UTF-8格式的字符串将导致乱码。
稍微解释一下,你的源代码是作为字节序列读取的。PHP使用ASCII解释所有重要的内容(关键字、运算符等等)。UTF-8向后兼容ASCII。这意味着,所有“正常”的ASCII字符在ASCII和UTF-8中使用相同的字节表示。因此,无论是保存在ASCII还是UTF-8中,"都被PHP解释为"。PHP会将引号之间的任何内容直接视为文字位序列。所以PHP把你的"あ"看作是"11100011 10000001 10000010",并不关心引号之间到底是什么,它只是按照原样使用。

3

PHP通常不关心字符串编码,字符串在PHP中是二进制数据,因此如果您需要编码,请了解字符串内部数据的编码。问题是:在您的情况下,编码是否重要?

如果您像这样设置了字符串变量的内容:

$string="ぁ";

它不包含UTF-8,而是包含一个无效的UTF-8字符二进制序列。这就是为什么浏览器或编辑器显示问号或类似符号的原因。所以在继续之前,您已经看到有些东西可能不是预期的。(结果证明是我的端口缺失了字体)
这也表明您在编辑器中的文件支持UTF-8或其他一些unicode编码。只需记住以下几点:一个文件 - 一个编码。如果您将字符串存储在文件中,则它位于该文件的编码中。检查您的编辑器以确定您保存文件的编码。然后您就知道字符串的编码。
让我们假设它是一些有效的UTF-8,比如(对我的字体的支持):
$string="ä";

您之后可以执行字符串的二进制比较:
if ( 'ä' === $string )
  # do your stuff

因为它在同一文件中且PHP字符串是二进制数据,所以这适用于每种编码。因此,如果您使用“二进制安全”的函数,则通常不需要重新编码(更改编码)数据-这意味着数据的编码未更改。
对于正则表达式,编码确实起到作用。这就是为什么有“u”修饰符的原因,它表示您想要使表达式在和使用Unicode编码的数据上工作。但是,如果数据已经是Unicode编码,则在使用preg_match之前不需要将其转换为Unicode。然而,在您的代码示例中,根本不需要正则表达式,简单的字符串比较即可完成任务。
总结:
$string="ä";
if ( 'ä' === $string )
  # do your stuff

为什么你说 $string="ぁ"; 如果我将文件编码为 UTF-8,它 不会包含 UTF-8,而是包含一个无效的二进制序列 - nEAnnam
因为像问号一样的字符,存在的并不是所有二进制序列都是有效的UTF-8字符(或者说精确地说是Unicode码点)。这就是为什么您的编辑器显示出那个问号,因为该二进制序列无法被“读取”为有效的字符。 - hakre
1
$string="ぁ"; 对我来说显示为日语的あ非常正常。那确实是一个有效的UTF-8字符。不确定你看到了什么... - deceze
@hakre,有些东西我从您的回答中无法理解,但非常感谢您的回答和时间。 - nEAnnam
@deceze,@nEAnnam:好的,在我的电脑上它显示了一个像 [?] 的字符,根据你们所写的内容,我现在确定我缺少一个字体。所以忽略那部分说它无效的内容,这是我的错误(:D)。只要它是有效的,就像 ä 一样,那部分应该仍然是有效的。已编辑答案,希望现在更好了。 - hakre

1

你的字符串不是utf-8字符,所以无法进行preg匹配,因此你需要使用utf8_encode对其进行编码。尝试将PHP文件编码为utf-8(使用类似Notepad++的工具),这样可能就不需要进行编码了。


我已经使用UTF-8对所有文件进行了编码,那么这个函数还有必要吗? - nEAnnam
你尝试过移除 utf8_encode 函数并查看是否匹配吗? - fire
如果我使用UTF-8编码文件,那么它就是真正的UTF-8字符串吗?所以那个函数不是必需的。 - nEAnnam
不,除非原始字符串来自可能不是UTF-8编码的用户输入。即使如此,utf8_encode也无法解决您的问题,因为它只能从ISO-8859-1进行转换。 - fire

0

摘要:

utf8_encode()函数将给定字符串中的每个字节编码为UTF-8。 无论之前使用什么编码存储文件。 它的目的是编码尚未为UTF-8的字符串¹。

1.- 正确使用此函数的方法是将ISO-8859-1字符串作为参数传递。 为什么?因为Unicode和ISO-8859-1在相同位置具有相同的字符。

                [Char][Value/Position]          [Encoded Value/Position]
[Windows-1252]  [€][80]                 ---->   [C2|80] Is this the UTF-8 encoded value/position of the [€]?    No
[ISO-8859-1]    [¢][A2]                 ---->   [C2|A2] Is this the UTF-8 encoded value/position of the [¢]?    Yes

这个函数似乎可以与其他编码一起工作:如果要编码的字符串只包含与ISO-8859-1编码相同值的字符(例如在Windows-1252中的00-EF & A0-FF位置),它就能正常工作。

需要注意的是,如果该函数接收到一个UTF-8字符串(以UTF-8编码的文件),它将再次对该UTF-8字符串进行编码,并产生垃圾数据。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接