当前位置: 首页 > 面试题库 >

如何处理用户输入的无效UTF-8字符?

籍利
2023-03-14
问题内容

我正在寻找有关如何处理来自用户的无效UTF-8输入的一般策略/建议。

即使我的Web应用程序使用UTF-8,还是有些用户输入了无效字符。这会导致PHP的json_encode()错误,并且总体而言似乎是个坏主意。

W3C I18N常见问题解答:多语言形式说:“如果接收到非UTF-8数据,则应将错误消息发送回去。”。

  • 在整个站点中有数十个可以输入数据的站点中,实际上该怎么做呢?
  • 您如何以有用的方式向用户显示错误?
  • 您如何临时存储和显示错误的表单数据,以使用户不会丢失所有文本?去除不良字符?使用替换字符,如何?
  • 对于数据库中的现有数据,当检测到无效的UTF-8数据时,我应该尝试将其转换并保存回去(如何?utf8_encode()?mb_convert_encoding()吗?),或者按原样保留在数据库中但要执行某些操作(什么?)在json_encode()之前?

编辑:我对mbstring扩展非常熟悉,而不是问“ UTF-8如何在PHP中工作”。 我想从经验丰富的人那里得到建议,以了解他们如何处理此问题。

EDIT2:作为解决方案的一部分,我真的很想看到一种 将无效字符转换为U + FFFD 的 快速 方法


问题答案:

accept-charset="UTF-8"属性仅是浏览器要遵循的准则,并不强迫他们以这种方式提交,笨拙的表单提交机器人就是一个很好的例子…

我最常做的就是忽略坏的字符,无论是通过iconv()还是有不太可靠utf8_encode()/
utf8_decode()功能,如果你使用iconv你也有音译坏字符的选项。

这是一个使用示例iconv()

$str_ignore = iconv('UTF-8', 'UTF-8//IGNORE', $str);
$str_translit = iconv('UTF-8', 'UTF-8//TRANSLIT', $str);

如果您想向您的用户显示错误消息,我可能会以全局方式而不是按接收到的每个值来执行此操作,类似这样的操作可能会很好:

function utf8_clean($str)
{
    return iconv('UTF-8', 'UTF-8//IGNORE', $str);
}

$clean_GET = array_map('utf8_clean', $_GET);

if (serialize($_GET) != serialize($clean_GET))
{
    $_GET = $clean_GET;
    $error_msg = 'Your data is not valid UTF-8 and has been stripped.';
}

// $_GET is clean!

您可能还需要规范化新行并去除(不)可见的控制字符,如下所示:

function Clean($string, $control = true)
{
    $string = iconv('UTF-8', 'UTF-8//IGNORE', $string);

    if ($control === true)
    {
            return preg_replace('~\p{C}+~u', '', $string);
    }

    return preg_replace(array('~\r\n?~', '~[^\P{C}\t\n]+~u'), array("\n", ''), $string);
}

从UTF-8转换为Unicode代码点的代码:

function Codepoint($char)
{
    $result = null;
    $codepoint = unpack('N', iconv('UTF-8', 'UCS-4BE', $char));

    if (is_array($codepoint) && array_key_exists(1, $codepoint))
    {
        $result = sprintf('U+%04X', $codepoint[1]);
    }

    return $result;
}

echo Codepoint('à'); // U+00E0
echo Codepoint('ひ'); // U+3072

可能 比任何其他替代产品都快,但是尚未对其进行广泛的测试。

例:

$string = 'hello world�';

// U+FFFEhello worldU+FFFD
echo preg_replace_callback('/[\p{So}\p{Cf}\p{Co}\p{Cs}\p{Cn}]/u', 'Bad_Codepoint', $string);

function Bad_Codepoint($string)
{
    $result = array();

    foreach ((array) $string as $char)
    {
        $codepoint = unpack('N', iconv('UTF-8', 'UCS-4BE', $char));

        if (is_array($codepoint) && array_key_exists(1, $codepoint))
        {
            $result[] = sprintf('U+%04X', $codepoint[1]);
        }
    }

    return implode('', $result);
}

这是您要找的东西吗?



 类似资料:
  • 问题内容: 网络服务器使用utf-8编码提供响应,所有文件都使用utf-8编码保存,我所知的所有设置都已设置为utf-8编码。 这是一个快速程序,用于测试输出是否有效: 该程序的输出为: 呈现为: 我可能做错了什么?我必须告诉DomDocument正确处理utf-8的具体程度是多少? 问题答案: 需要一个HTML字符串。 HTML 根据其规范使用默认的编码(ISO拉丁字母1号)。那是因为更长,请参

  • 问题内容: 下面是测试程序,包括一个汉字: 以下是结果,请看json.dumps将utf-8转换为原始数字! 为什么这坏了?还是我错了? 问题答案: 您应该阅读json.org。完整的JSON规范在右侧的白框中。 生成的JSON没有错。允许生成器生成UTF-8字符串或纯ASCII字符串,在这些字符串中使用符号转义字符。在您的情况下,Python 模块决定转义,并使用转义符号。 顺便说一句:任何符合

  • 如何使用位于。 我得到的错误: 我不确定什么非utf-8字符是在,但不是在。 我在网上看到过很多类似的教程,但对于其他情况,这些教程并不完整或复杂。我想询问社区并研究如何使用rust中各种情况和模块的代码。如果您想在下面对我目前不确定的两个案例发表意见,我们将不胜感激。 使用中的代码main.rs(了解) 在中使用中的代码(了解) 在中使用中的代码(理解) 使用中的代码main.rs(了解) 在中

  • 问题内容: 当(杰克逊,在这种情况下)JSON引擎尝试解析一些未使用UTF-8编码的JSON时,会发生此错误。 如何告诉引擎它应该期望与UTF-8不同的东西,例如UTF-16? 错误日志: 问题答案: JSON数据必须编码为UTF-8,UTF-16或UTF-32。JSON解码器可以通过检查字节流的前四个八位字节来确定编码: 听起来好像服务器正在以某种非法编码(ISO-8859-1,Windows-

  • 在Java中,我向JSON对象添加一些属性,并将这些值发送到HTTPS URL(REST API)。服务器抛出一些错误,如“无效的utf-8开始字节0xb0”。下面是我的代码:

  • 我使用jMeter通过post请求向测试服务器发送json。 以下请求总是失败: 响应数据中的错误消息为: 请求根本不发送到服务器。其他请求(例如将类别中的值替换为其他有效类别,如“Delis”)工作完美。 我猜这是一个与“Café”有关的编码问题,但我不知道如何解决它。知道吗?谢谢