在 PHP 中清理 UTF-8


Sanitise UTF-8 in PHP

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

  1. 它应该是非常简单和强大的东西。
  2. 错误出在用于手动检查的模块中,因此mojibake很好。
  3. 负责修复编码的代码位于不同的模块中。(不过,它坏了。我不想重复责任。

无效字符串示例的十六进制表示形式:496e76616c6964206d61726b2096

我目前的解决方案:

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

我的代码的三个问题:

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

有什么更好的主意吗?

有类似的问题,确保PHP中的有效UTF-8,但我不在乎转换。

你应该

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

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

$raw_str = hex2bin('496e76616c6964206d61726b2096');
$sane_str = mb_convert_encoding($raw_str, 'UTF-8', 'UTF-8');
您可以使用

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;
}

函数json_encode需要一个 UTF-8 编码的字符串。使用基于 W3C 推荐的正则表达式答案的函数检查编码 确保 PHP 中的 UTF-8 有效

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);