当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何处理无效UTF-8字符的用户输入?》经验,为你挑选了1个好方法。

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

即使我的webapp使用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 的快速方法



1> Alix Axel..:

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

这是你在找什么?


@philfreo:好的,这个是必读的:http://webcollab.sourceforge.net/unicode.html.
推荐阅读
Gbom2402851125
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有