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

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

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

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

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

回答:

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

}


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字符? 的全部内容, 来源链接: utcz.com/qa/427889.html

回到顶部