UTF-8字符串的解码会损坏一个字符串,但不会损坏另一个字符串


Decode of UTF-8 String corrupts one string, but not another

我有一个非常奇怪的错误。

我已经验证了我的两个字符串都是UTF-8(通过mb_check_encoding和mb_detect_encoding进行检查),但当我试图在字符串上使用utf8_decode时,它会向我返回垃圾字符。在这种情况下,我实际上不需要使用utf8 _decode,字符串将是正常的。

困难在于,我有一些客户使用UTF-8数据库,我从中提取字符串,并使用utf8_decode为PHP解开字符串。如果我不这样做,空格字符将被替换为A。他们共享相同的代码来生成字符串,但由于某种原因,当我为另一个客户生成字符串时,字符串会出错。

除了字符串是utf8之外,还有什么方法可以验证我是否需要使用utf8_decode?

一些例子:

Using utf8_decode for customer 1:
?0,107�per�km
Without utf8_decode for customer 1:
€0,107 per km
Using utf8_decode for customer 2:
$7.00 per km
Without utf8_decode for customer 2:
$7.00 per km

谢谢大家!

没有知情的detect_ordermb_detect_encoding不是银弹,这将证明:

$ php -r 'echo mb_detect_encoding(iconv("utf-8","iso-8859-1","ë"));'
UTF-8

显然是错误的,将其设置为严格有点帮助:

$ php -r 'var_dump(mb_detect_encoding(iconv("utf-8","iso-8859-1","ë"),mb_detect_order(),true));'
bool(false)

为什么它是假的?好吧,让我们研究一下mb_detect_encoding()在我的配置中可能使用的字符集:

$ php -r 'var_dump(mb_detect_order());'
array(2) {
  [0] =>
  string(5) "ASCII"
  [1] =>
  string(5) "UTF-8"
}

好吧,除了ASCII&UTF-8,则不会检测到其他字符集。不过Jon有一点:你可以将其全部存储为utf-8,只要有适当的数据库设置,甚至在mysql中只存储一个正确的character_set_results(我假设你使用…)连接,就可以将其作为utf-8进行检索,而不管它是如何存储的。然而,如果出于我想不出的任何原因,这不是一个选项,则由指定哪些字符集可以用于mb_detect_order

$ php -r 'echo mb_detect_encoding(iconv("utf-8","iso-8859-1","ë"),"ASCII,UTF-8,ISO-8859-1,JIS", true);'
ISO-8859-1

简而言之:负责提供可能的字符集列表,如果您已经拥有此类信息。。。您可能知道字符集(通过连接设置、数据库/表设置,甚至只是客户端配置等),而不是尝试检测