UTF-8 字符的 Codeigniter 4 本地化问题
Codeigniter 4 localization issue with UTF-8 characters
上下文
我正在尝试对某些文本执行 lemmatization,我发现我可以为此使用 CI4 本地化。基本上我在 \App\Languages\ro-RO 中创建了一些文件,并且我将这些词“t运行slating”到它们的语言词根。
语言文件以 UTF-8 编码(我在服务器上用 file -i
命令检查过)。 PHP 将 UTF-8 作为默认字符集。 Apache 有一个 AddDefaultCharset UTF-8
设置。
每个页面的 header 都有正确的声明 header('Content-Type: text/html; charset=UTF-8');
。在 CI 中,我将 App.php 配置为 public $charset = 'UTF-8'
和 public $defaultLocale = 'ro-RO';
。在服务的每个页面的 header 中,我还放置了命令:
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_http_input('UTF-8');
mb_regex_encoding('UTF-8');
问题
只要标签包含罗马尼亚语变音符号 ş 或 ş,lang() 函数就无法找到 t运行slation。相反,它与其他罗马尼亚语变音符号(ă、î 和â)配合使用效果很好。显然 ş 和 ş 是拉丁语扩展 B 的一部分,而其他的是拉丁语扩展 A.
奇怪的是,mb_ord() 没有 return 任何这些变音符号的整数值。我做了一个小函数来获取每个单词并逐个字母地显示它以及字符代码。你可以看到结果($chunks
是一个包含单词的数组,clean_character
函数只是检查 mb_ord return 是否是一个整数):
private function displayTextInfo( $chunks ) {
for ($i=0; $i<count($chunks); $i++):
echo $chunks[$i] . ' - ';
for ($j=0; $j<strlen($chunks[$i]); $j++):
$char = substr($chunks[$i], $j, 1);
if ( $this->clean_character($char) ) {
echo $char . '(' . mb_ord( $char, 'UTF-8' ) . ') ';
} else {
echo $char . '(???)';
}
endfor;
echo '<br>';
endfor;
}
formaţiune - f(102) o(111) r(114) m(109) a(97) �(???)�(???)i(105) u(117) n(110) e(101)
depăşit - d(100) e(101) p(112) �(???)�(???)�(???)�(???)i(105) t(116)
我在互联网上走来走去,但找不到对此的解释。我运行没主意了。
有什么想法吗?
阅读了很多与 Unicode 和罗马尼亚变音符号相关的文章,了解了一些历史。看来微软在早期的罗马尼亚字符集上犯了一个错误,将ș
和ț
误写为ş
和ţ
。您可能没有注意到区别,但确实存在:第一个字符在 s 和 t 下方有一个逗号,而后者有一个后缀。人眼几乎察觉不到它,但计算机的感知力更强:-)。 Unicode 是第一个纠正这个错误的标准,但它带来了很多问题,因为很多数据已经在使用“错误”的字符。这使得罗马尼亚语的文本搜索变得更加复杂。
这其实也是我的问题。语言文件以 UTF-8 正确编码,但它们很可能是使用 ISO-8859-2 创建的,其中包含 ş 和 ş 的“错误”字符。我只需要将“错误”字符完全替换为“正确”字符即可。
我在这里记录了这一点,希望它能对将来的人有所帮助,因为注意到 ş 和 ş 两种表示形式之间微小的视觉差异不是小菜一碟。这让我沮丧了一天。
上下文
我正在尝试对某些文本执行 lemmatization,我发现我可以为此使用 CI4 本地化。基本上我在 \App\Languages\ro-RO 中创建了一些文件,并且我将这些词“t运行slating”到它们的语言词根。
语言文件以 UTF-8 编码(我在服务器上用 file -i
命令检查过)。 PHP 将 UTF-8 作为默认字符集。 Apache 有一个 AddDefaultCharset UTF-8
设置。
每个页面的 header 都有正确的声明 header('Content-Type: text/html; charset=UTF-8');
。在 CI 中,我将 App.php 配置为 public $charset = 'UTF-8'
和 public $defaultLocale = 'ro-RO';
。在服务的每个页面的 header 中,我还放置了命令:
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_http_input('UTF-8');
mb_regex_encoding('UTF-8');
问题
只要标签包含罗马尼亚语变音符号 ş 或 ş,lang() 函数就无法找到 t运行slation。相反,它与其他罗马尼亚语变音符号(ă、î 和â)配合使用效果很好。显然 ş 和 ş 是拉丁语扩展 B 的一部分,而其他的是拉丁语扩展 A.
奇怪的是,mb_ord() 没有 return 任何这些变音符号的整数值。我做了一个小函数来获取每个单词并逐个字母地显示它以及字符代码。你可以看到结果($chunks
是一个包含单词的数组,clean_character
函数只是检查 mb_ord return 是否是一个整数):
private function displayTextInfo( $chunks ) {
for ($i=0; $i<count($chunks); $i++):
echo $chunks[$i] . ' - ';
for ($j=0; $j<strlen($chunks[$i]); $j++):
$char = substr($chunks[$i], $j, 1);
if ( $this->clean_character($char) ) {
echo $char . '(' . mb_ord( $char, 'UTF-8' ) . ') ';
} else {
echo $char . '(???)';
}
endfor;
echo '<br>';
endfor;
}
formaţiune - f(102) o(111) r(114) m(109) a(97) �(???)�(???)i(105) u(117) n(110) e(101)
depăşit - d(100) e(101) p(112) �(???)�(???)�(???)�(???)i(105) t(116)
我在互联网上走来走去,但找不到对此的解释。我运行没主意了。
有什么想法吗?
阅读了很多与 Unicode 和罗马尼亚变音符号相关的文章,了解了一些历史。看来微软在早期的罗马尼亚字符集上犯了一个错误,将ș
和ț
误写为ş
和ţ
。您可能没有注意到区别,但确实存在:第一个字符在 s 和 t 下方有一个逗号,而后者有一个后缀。人眼几乎察觉不到它,但计算机的感知力更强:-)。 Unicode 是第一个纠正这个错误的标准,但它带来了很多问题,因为很多数据已经在使用“错误”的字符。这使得罗马尼亚语的文本搜索变得更加复杂。
这其实也是我的问题。语言文件以 UTF-8 正确编码,但它们很可能是使用 ISO-8859-2 创建的,其中包含 ş 和 ş 的“错误”字符。我只需要将“错误”字符完全替换为“正确”字符即可。
我在这里记录了这一点,希望它能对将来的人有所帮助,因为注意到 ş 和 ş 两种表示形式之间微小的视觉差异不是小菜一碟。这让我沮丧了一天。