【问题标题】:Sanitise UTF-8 in PHP在 PHP 中清理 UTF-8
【发布时间】:2016-04-27 12:24:12
【问题描述】:

函数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 可能忽略太多:整个字符串。

有更好的主意吗?

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

【问题讨论】:

  • 如果你不关心转换......那你想做什么?
  • 我需要一个有效的 UTF-8 字符串用于 json_encode。有效的 mojibake 很好。就是这样。
  • 老实说,您的解决方案是我能看到的最干净的解决方案。如果您不想使用@,您可能希望通过编码检查运行字符串,这很麻烦。

标签: php utf-8 sanitization


【解决方案1】:

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

【讨论】:

  • 更多的是评论而不是答案!在制作 cmets 时使用 cmets 顺便说一句,我不赞成
  • 请不要使用答案来提出澄清问题。
  • 抱歉,还在学习系统。虽然我认为这是他正在寻找的功能。
  • @raphael75 你应该修改你的答案,以便有信心支持它,而不是提出问题(它只是为不确定性留下了空间)。您将获得 + 票而不是减票 ;-) Stack pro-tip
  • @raphael75 根据您的编辑,您的回答现在更有意义了 ;-)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    您可以使用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;
    }
    

    【讨论】:

      【解决方案4】:

      函数json_encodeexpects a 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);
      

      【讨论】:

        猜你喜欢
        • 2011-09-08
        • 2020-01-20
        • 2012-01-27
        • 2017-11-20
        • 1970-01-01
        • 2012-01-20
        • 2012-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多