为什么mbstring函数无法正确识别ISO-8859字符串?

3
尽管每个ISO-8859字符集被列为单独的编码,但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
使用相同的所有列出语言生成相同的结果,这显然是错误的。

为什么mbstring单独列出每个ISO-8859编码,但对它们进行可互换处理?是否有可靠的方法来检测正确的规范?

还是我只是误用了这些函数?


mb_detect_encoding 猜测编码方式,但这种猜测并不准确(而且该函数也没有太多尝试去做),而 mb_check_encoding 只是告诉你一个字符串是否由给定编码的字节序列组成。 - user3942918
应该完全删除 mb_detect_encoding,它没有任何价值,只会让人感到困惑。 - user3942918
@PaulCrovella老实说,这是我第一次尝试使用mbstring函数 - 我没有意识到它们的限制,也没有调查它们的实际实现。我试图找出一种方法来为不同的字母表排序字符串,而不必手动组装正则表达式。 - bosco
@bosco intl扩展拥有许多非常有用的工具,例如IntlChar,可以帮助处理这些问题。如果你还没有熟悉它,那么值得花时间去了解一下。 - user3942918
@PaulCrovella 我一定会这样做 - 早就该跟上国际化的步伐了。感谢您的启发!如果您愿意在回答中提供有关 mbstring 函数仅检查字节序列的信息,那么它肯定可以满足我的问题。再次感谢。 - bosco
显示剩余5条评论
1个回答

3

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 - bosco
它并没有直接解决这个问题,无论是mbstring还是8859,但它确实有助于理解编码的本质。将此与将PHP中的字符串视为一堆字节而不是一堆字符相结合,所有种类的事情都会更加清晰,相关问题也会更容易理解。 - user3942918

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