Php 混合编码,让一切都成为UTF-8

Php 混合编码,让一切都成为UTF-8,php,unicode,utf-8,iso-8859-1,Php,Unicode,Utf 8,Iso 8859 1,我有一些具有不同编码的文本,例如以下文本,具有UTF-8和ISO-8859-1的混合编码: محتوای میکس شده و بخش سالم 但我希望所有这些都变成UTF-8,这意味着剩下UTF-8编码的部分,其他字符串变成UTF-8,例如,上面的文本应该输出为: محتوای میکس شده و بخش سالم 我使用了不同的方法,在PHP中使用iconv函数并使用以下类: 但是他们都没有给我正确的输出,而且文本的某些部分总是成为问号,比如????? 将

我有一些具有不同编码的文本,例如以下文本,具有UTF-8和ISO-8859-1的混合编码:

محتوای میکس شده و بخش سالم
但我希望所有这些都变成UTF-8,这意味着剩下UTF-8编码的部分,其他字符串变成UTF-8,例如,上面的文本应该输出为:

محتوای میکس شده و بخش سالم
我使用了不同的方法,在PHP中使用
iconv
函数并使用以下类:

但是他们都没有给我正确的输出,而且文本的某些部分总是成为问号,比如
?????

将混合编码转换为UTF-8而不造成任何损坏的最佳方法是什么

编辑:

混合文本的行字节数:

c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985
正确文本:

محتوای میکس شده و بخش سالم

关于@Nulled确认数据来自数据库的应答,我可以确认问题来自表或数据库的错误编码。 我以前遇到过这个问题,我通过在使用此查询获取数据之前强制使用数据库/表编码(您需要将其更新为您的数据库/表编码)解决了这个问题:

例如:

$this->db->query('SET NAMES latin1;');
$this->db->query('SELECT * FROM table')->result();

字符串的一部分是Windows-1252 mojibake,这意味着在某个点上UTF-8字符串被解释为Windows-1252,并从错误的假设转换为UTF-8。这可以通过将字符串从UTF-8转码到Windows-1252来逆转,从而得到正确的原始UTF-8序列。要仅将该转换应用于混乱的文本子集,可以使用正则表达式,例如,仅将转换应用于文本的非阿拉伯语部分:

// sample data
$str_hex = 'c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985';
// actual string
$str = hex2bin($str_hex);

echo 'Messed up: ', $str, PHP_EOL;  // محتوای میکس شده و بخش سالم

$fixed = preg_replace_callback(
    '/\\P{Arabic}+/u',  // matches non-Arabic sequences
    function (array $m) { return iconv('UTF-8', 'Windows-1252', $m[0]); }, 
    $str
);

echo 'Fixed: ', $fixed;  // محتوای میکس شده و بخش سالم

这些实际上是混合编码,还是mojibake(错误转换的文本)与非mojibake混合?不管是哪种方式,你们都被搞砸了。这些是混合编码。给我们一个原始字节的示例,以及你们希望它对应的文本。还有,它是如何结束的,你不能在源代码上修复它吗?我问题中的示例文本是什么,第二个是必须的,你需要更多的文本吗?这些来自旧数据库,我不知道这是怎么发生的。我不应该对数据库做任何更改。该示例确认您有一个UTF-8编码的字符串,字面上包含字符Ù,…,Ø等,还有字符ل,م等。好吧,是的,您被搞砸了。看起来像是编码错误的Window-1252 mojibake。如果您完全确定文本应该是阿拉伯语,您可能可以选择非阿拉伯语的字符范围,并使用
iconv('UTF-8','Windows-1252',$substr')
修复它们的编码。鉴于OP提供的示例数据,这不会有帮助。问题是混合编码而不是Unicode编码,如果我将名称设置为latin1,正确的字符串受到损坏。你试过了吗?您是否尝试将其与utf8_encode()结合使用?
// sample data
$str_hex = 'c399e280a6c398c2adc398c2aac399cb86c398c2a7c39bc59220c399e280a6c39bc592c39ac2a9c398c2b320c398c2b4c398c2afc399e280a120d98820d8a8d8aed8b420d8b3d8a7d984d985';
// actual string
$str = hex2bin($str_hex);

echo 'Messed up: ', $str, PHP_EOL;  // محتوای میکس شده و بخش سالم

$fixed = preg_replace_callback(
    '/\\P{Arabic}+/u',  // matches non-Arabic sequences
    function (array $m) { return iconv('UTF-8', 'Windows-1252', $m[0]); }, 
    $str
);

echo 'Fixed: ', $fixed;  // محتوای میکس شده و بخش سالم