UTF-8 可以存储任何 Unicode 字符。如果您的编码是其他任何东西,包括ISO-8859-1或Windows-1252,UTF-8可以存储其中的每个字符。因此,当您将字符串从任何其他编码转换为 UTF-8 时,不必担心丢失任何字符。
此外,ISO-8859-1 和 Windows-1252 都是单字节编码,其中任何字节都有效。从技术上讲,无法区分它们。我会选择Windows-1252作为非UTF-8序列的默认匹配项,因为解码方式不同的字节是唯一0x80-0x9F范围。这些解码为各种字符,如Windows-1252中的智能引号和欧元,而在ISO-8859-1中,它们是几乎从未使用的不可见的控制字符。Web浏览器有时可能会说他们正在使用ISO-8859-1,但通常他们会真正使用Windows-1252。
此代码是否可确保字符串可以安全地插入到 UTF-8 编码文档中
为此,您肯定希望将可选的“strict”参数设置为 TRUE。但我不确定这是否真的涵盖了所有无效的UTF-8序列。该函数不声明显式检查字节序列的 UTF-8 有效性。在已知的情况下,mb_detect_encoding以前会错误地猜测UTF-8,尽管我不知道这是否仍然可以在严格模式下发生。
如果您想确定,请使用W3推荐的正则表达式自己动手:
if (preg_match('%^(?:
[\x09\x0A\x0D\x20-\x7E] # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)*$%xs', $string))
return $string;
else
return iconv('CP1252', 'UTF-8', $string);