用PHP清理UTF-8

时间:2016-04-27 12:24:13

标签: php utf-8 sanitization

函数json_encode需要有效的UTF-8字符串。我的字符串可能采用不同的编码方式。我需要忽略或替换所有无效字符才能转换为JSON。

  1. 它应该是非常简单和健壮的东西。
  2. 错误在模块中进行手动检查,因此mojibake很好。
  3. 负责修复编码的代码位于不同的模块中。 (它被打破了,想。)我不想重复责任。
  4. 无效字符串示例的十六进制:496e76616c6964206d61726b2096

    我目前的解决方案:

    $raw_str = hex2bin('496e76616c6964206d61726b2096');
    $sane_str = @\iconv('UTF-8', 'UTF-8//IGNORE', $raw_str);
    

    我的代码存在三个问题:

    1. iconv看起来有点太重了。
    2. 许多程序员不喜欢@
    3. iconv可能会忽略太多:整个字符串。
    4. 有更好的主意吗?

      有类似的问题,但我不关心转换。 Ensuring valid utf-8 in PHP

4 个答案:

答案 0 :(得分:3)

您应该查看mb_convert_encoding。它能够将文本从几乎任何编码转换为另一种编码。我不得不将它用于类似的项目:http://php.net/manual/en/function.mb-convert-encoding.php

答案 1 :(得分:1)

json_encode expects UTF-8 encoded string。使用基于Ensuring valid utf-8 in PHP

中W3C推荐的正则表达式答案的函数检查编码
function encodeUtf8($string){
 if (preg_match('%^(?:
      [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    | \xE0[\xA0-\xBF][\x80-\xBF]         # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    | \xED[\x80-\x9F][\x80-\xBF]         # excluding surrogates
    | \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
 )*$%xs', $string))
    return $string;
 else
    return iconv('CP1252', 'UTF-8', $string);
}

然后你可以使用它:

$sane_str = encodeUtf8($raw_str);

答案 2 :(得分:1)

您可以使用mb_detect_encoding来检测它是否不是UTF-8,然后使用mb_convert_encoding将文本转换为UTF-8

<?php
/**
 * Convert json blob to UTF-8
 * @param $string String to be decoded
 * @return bool|string
 */
function convert_json($string)
{
    if (ctype_print($string)) { // binary
        return false;
    }
    $from = mb_detect_encoding($string, ['auto']);
    $to = 'UTF-8';
    if ($from !== $to) {
        $string = mb_convert_encoding($string, $to, $from);
    }
    return $string;
}

答案 3 :(得分:1)

我认为这是最好的解决方案。

$raw_str = hex2bin('496e76616c6964206d61726b2096');
$sane_str = mb_convert_encoding($raw_str, 'UTF-8', 'UTF-8');