在PHP字符串中查找unicode失败


Find unicode fails in PHP string

我目前正在一个接受英语,俄语和乌克兰语输入的网站工作。

用户提交的表单通常使用商标符号(™)、日文字母(*)和德文字母(Ö)等字符。

这很好,但有时当他们从某个地方复制粘贴这些字符时,他们会提交输入,如:(0xD8000xDC00)(0xFFFD)(0x17),¿(0xBF),½(0xBD)和ï (0xEF)(顺便说一下,有一个乌克兰字母' _ ',它的值是0x457)。

稍后,当将该输入转换为UTF-8 XML时,它会抛出此错误"输入不符合UTF-8,请指示编码! "字节:0x17 0xEF 0xBF 0xBD,第13330行,第27列".

是否有一种方法来验证这些"破碎"字符在用户输入?

我正在考虑将每个字符从输入字符串转换为十六进制值,然后与包含所有非法十六进制值的数组进行比较。但在这种方法中,问题是我不知道"破碎"字符的所有可能代码。我知道0xEF 0xBF 0xBD经常出现,但我不知道还有多少。

有什么建议吗?

如果包含表单的网页是用UTF-8编码的,那么每个现代浏览器都应该提交用有效UTF-8编码的表单字段。(不过,您仍然应该在服务器上验证这一点。)我觉得这里发生的事不太一样。字节序列

0x17 0xEF 0xBF 0xBD

是有效的UTF-8: U+0017传输结束块后面跟着U+FFFD替换字符。但是您提到了XML处理,而U+0017在XML 1.0中是无效的。XML 1.0只允许

#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]

(XML 1.1部分解除了这个限制。)我建议在将XML中不允许的ASCII控制字符传递给XML处理函数之前,用替换字符替换它们:

preg_replace('/['x00-'x08'x0B'x0C'x0E-'x1F]/', "'xEF'xBF'xBD", $value);

或者,也包括U+FFFE和U+FFFF:

preg_replace('/['x00-'x08'x0B'x0C'x0E-'x1F'x{FFFE}'x{FFFF}]/u', "'xEF'xBF'xBD", $value);

也许iso-8859-1可以。

我不知道这是不是答案,你可以试一试。