Php 如何转换格式错误的数据库字符(ascii到utf-8)
我知道很多人会说这个问题已经得到了这样的回答,但让我解释一下为什么它不那么直截了当 我想用PHP将“看起来像ascii”的东西转换成“utf-8” 有一个网站可以做到这一点 当我输入这个字符串时,我返回Php 如何转换格式错误的数据库字符(ascii到utf-8),php,character-encoding,non-ascii-characters,Php,Character Encoding,Non Ascii Characters,我知道很多人会说这个问题已经得到了这样的回答,但让我解释一下为什么它不那么直截了当 我想用PHP将“看起来像ascii”的东西转换成“utf-8” 有一个网站可以做到这一点 当我输入这个字符串时,我返回Z⬦Z这是正确的输出 我尝试了iconv和一些mb函数。虽然我不知道这些函数是否能够实现我想要的功能,或者我需要哪些选项。如果无法使用这些函数,请使用一些自行编写的PHP代码。(该网站运行javascript,我不认为PHP在这方面的能力有所下降) 需要明确的是:目标是用PHP重新创建该网站正在做
Z⬦Z
这是正确的输出
我尝试了iconv
和一些mb
函数。虽然我不知道这些函数是否能够实现我想要的功能,或者我需要哪些选项。如果无法使用这些函数,请使用一些自行编写的PHP代码。(该网站运行javascript,我不认为PHP在这方面的能力有所下降)
需要明确的是:目标是用PHP重新创建该网站正在做的事情。不要对ascii和utf-8进行语义辩论
编辑:使用
它可以根据编码标准对任何标量Unicode码点值进行编码/解码
标准链接到,所以这个库说它实现了标准,那么PHP呢?UTF-8是ASCII的超集,所以从ASCII转换为UTF-8就像将汽车转换成汽车一样
+--- UTF-8 ---------------+
| |
| +--- ASCII ---+ |
| | | |
| +-------------+ |
+-------------------------+
您链接的工具似乎使用术语“ASCII”作为同义词(它表示“汽车”,但表示“废金属”)。Mojibake通常是这样发生的:
⬦代码>
0xE2 0xAC 0xA6
->0xE2
->0xAC
,
->0xA6
0xC3 0xA2
=,
0xC2 0xAC
==0xC2 0xA6
0xE2 0xAC 0xA6
(⬦代码>)也输入UTF-8流0xC3 0xA2 0xC2 0xAC 0xC2 0xA6
()
)
要撤消此操作,需要反向执行这些步骤。如果您知道使用了什么代理编码(在我的示例中是Windows-1252),那么这很简单:
但如果你不这样做,那就很棘手了。我想你可以:
编译一个字典,把你在不同的单字节编码中得到的不同字节序列编成字典,然后使用某种贝叶斯推理找出最可能的编码。(我真的帮不了你。)
尝试最可能的编码并目视检查输出,以确定哪个是正确的:
// Source code saved as UTF-8
$mojibake = "Z…Z";
foreach (mb_list_encodings() as $proxy) {
$original = mb_convert_encoding($mojibake, $proxy, 'UTF-8');
echo $proxy, ': ', $original, PHP_EOL;
}
如果(在您的案例中)您知道原始文本是什么,并且您确信没有混合编码,请按#2执行,但尝试PHP支持的所有编码:
// Source code saved as UTF-8
$mojibake = 'Z…Z';
$expected = 'Z⬦Z';
foreach (mb_list_encodings() as $proxy) {
$current = @mb_convert_encoding($mojibake, $proxy, 'UTF-8');
if ($current === $expected) {
echo "$proxy: match\n";
}
}
(这会打印出wchar:match
;不确定这是什么意思。)
是否有一个php函数可以从转到\xC3\xA2\xC2\xAC\xC2\xA6
?这似乎是第一次开始时遗漏的一步。否则答案很好!如果你的编辑器被配置为将文件保存为UTF-8,那么这两个字符串之间根本没有区别。我用两个十六进制编辑器(bless和wxHexEditor)尝试了这个方法,并检查了一个包含内容的文件。两个编辑器都显示了c3a2e282acc2a6
。这对于来说是正确的(来自wchar
)。我的例子是,
(来自Windows-1252
)。
// Source code saved as UTF-8
$mojibake = "Z…Z";
foreach (mb_list_encodings() as $proxy) {
$original = mb_convert_encoding($mojibake, $proxy, 'UTF-8');
echo $proxy, ': ', $original, PHP_EOL;
}
// Source code saved as UTF-8
$mojibake = 'Z…Z';
$expected = 'Z⬦Z';
foreach (mb_list_encodings() as $proxy) {
$current = @mb_convert_encoding($mojibake, $proxy, 'UTF-8');
if ($current === $expected) {
echo "$proxy: match\n";
}
}