【问题标题】:Why do mbstring functions incorrectly identify ISO-8859 strings?为什么 mbstring 函数无法正确识别 ISO-8859 字符串?
【发布时间】:2017-08-18 08:03:52
【问题描述】:

尽管有listing each ISO-8859 character set as an individual encoding,mbstring 函数可互换地处理每个ISO-8859 字符集。把重点带回家:

$strings = [ 
  'English'   => 'Ea vim decore sapientem repudiandae. Sea cu delenit gamu mutn, tic.',
  'Cyrillic'  => 'Лорем ипсум долор сит амет, ин ехерци вереар номинати яуи, сит ин омниум инермис но.',
  'Greek'     => 'Λορεμ ιπσθμ δολορ σιτ αμετ, ηασ γραεcο νθσqθαμ cθ, εστ θτ εσσε διcαμ qθαλισqθε cθ.',
  'Armenian'  => 'լոռեմ իպսում դոլոռ սիթ ամեթ, եամ նո թաթիոն ծոմպռեհենսամ, իուս ադ նիսլ ոմնիս մինիմ եսթ',
  'Georgian'  => 'ლორემ იფსუმ დოლორ სით ამეთ, ეხ ყუანდო ცოფიოსაე უსუ, იუს ეუ ჰინც ვერო დომინგ ჰის',
  'Hindi'     => 'वर्ष एसेएवं व्याख्यान संदेश होने लक्षण एसेएवं पहोचाना विचरविमर्श? वर्णन करती आशाआपस अन्तरराष्ट्रीयकरन. रहारुप कार्यसिधान्त',
  'Korean'    => '모든 국민은 보건에 관하여 국가의 보호를 받는다, 전직대통령의 신분과 예우에 관하여는 법',
  'Arabic'    => 'مع لهذه الهجوم عدم, فكان اتفاق الصفحات من أسر. وجزر عُقر أما بـ, عل دار بقسوة المتّبعة بالولايات. وإقامة والفرنسي كل لكل. أي',
  'Hebrew'    => 'עמוד מדינות, חפש ואלקטרוניקה אנתרופולוגיה דת, מה קהילה הקהילה טכנו'
];

$encodings = ['ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15' ];

foreach( $strings as $lang => $text ) {
    echo $lang . " is encoded as " . mb_detect_encoding( $text, $encodings ) . "\n";

    foreach( $encodings as $encoding ) {
        echo " - is " . (mb_check_encoding( $text, $encoding ) ? "" : "not ") . $encoding . "\n";
    }
}

这会产生如下效果的输出

Hindi is encoded as ISO-8859-1
  - is ISO-8859-1
  - is ISO-8859-2
  - is ISO-8859-3
  - is ISO-8859-4
  - is ISO-8859-5
  - is ISO-8859-6
  - is ISO-8859-7
  - is ISO-8859-8
  - is ISO-8859-9
  - is ISO-8859-10
  - is ISO-8859-13
  - is ISO-8859-14
  - is ISO-8859-15

with identical results for every listed language,这显然不是真的。

为什么 mbstring 会分别列出每个 ISO-8859 编码,但可以互换处理?有什么方法可以可靠地检测到正确的规格吗?

或者我只是在滥用这些功能?

【问题讨论】:

  • mb_detect_encoding 猜测编码可能是什么,这种事情不可能是准确的(而且这个函数没有太多尝试),@987654329 @ 只是告诉你一个字符串是否包含一个对给定编码有效的字节序列。
  • 请改用echo $lang . " is encoded as " . mb_detect_encoding( $text ) . "\n";。看看区别
  • @PaulCrovella 我明白了......这很不幸:/
  • @RiggsFolly 我当然看到了区别——我只是希望 mbstring 函数可以区分不同的ISO-8859 编码。似乎该模块应该将它们全部组合为ISO-8859,而不是在它实际上没有必要的逻辑来区分它们时单独列出它们。
  • mb_detect_encoding 应该完全删除,它没有价值,只会让人迷惑。

标签: php character-encoding iso-8859-1 mbstring


【解决方案1】:

mb_detect_encoding 猜测编码可能是什么,这种事情不可能准确(而且这个函数没有太多尝试。)

mb_check_encoding 告诉您字符串是否包含对给定编码有效的字节序列,并且假设每个可能的字节在每个 ISO-8859-* 中都是有效的,因此对它们进行验证是没有意义的(这些总是会返回true.)

相关阅读我非常推荐:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets

【讨论】:

  • 可悲的是,在我对 mbstring 函数的简短研究过程中,该文章在我的搜索结果中出现了几次,但我从未访问过它。犯了错误 O.o
  • 它并没有直接解决这个问题,无论是 mbstring 还是 8859,但它确实有助于理解编码的确切含​​义。再加上将 PHP 中的字符串视为不是一堆字符而是一堆字节和各种东西会更有意义,并且相关的问题将更容易解决。
猜你喜欢
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 2015-12-08
  • 2022-01-11
  • 1970-01-01
  • 2010-12-02
相关资源
最近更新 更多