iconv with ascii // transit triggers ErrorException:“iconv():检测到输入字符串中的非法字符”

时间:2014-02-11 13:11:58

标签: php iconv

首先,我必须说;我是多语言转换的陌生人。

如果可能的话,我想以UTF-8形式使用mb_lowercase的字符串(就像干净的网址一样),我使用

$str = iconv("UTF-8", "ASCII//TRANSLIT", utf8_encode($str));
$str = preg_replace("/[^a-zA-Z0-9_]/", "", $str);
$str = mb_strtolower($str);

以满足我的要求(UTF8,小写字符串)

但是,当我使用CocoaRestClient强调“çokGüŞelLl”的功能时;我得到Ã作为$ str(感谢我的客户端?)和iconv触发错误抱怨输入字符串(Ã)中的非法字符。

iconv有什么问题? str已经由utf8_encode($str)编码为utf8。怎么可能是非法人物呢?

注意: 我在这里阅读了@iconv的问题,但我认为拥有空的数据库条目不是一个好的解决方案。


感谢所有答案,我会阅读并尝试了解每一个答案。

3 个答案:

答案 0 :(得分:2)

PHP函数utf8_encode()期望您的字符串被ISO-8859-1编码。如果不是,那么,你会得到有趣的结果。

确保您的数据是正确的UTF-8 ,然后将其保存到您的数据库:

// Validate that the input string is valid UTF-8
if (preg_match("//u", $string) === false) {
    throw new \InvalidArgumentException("String contains invalid UTF-8 characters.");
}

// Normalize to Unicode NFC form (recommended by W3C)
$string = \Normalizer::normalize($string);

现在一切都以相同的方式存储在我们的数据库中,当我们从数据库接收数据时,我们不再需要关心这个问题。

$string = $database->getSomeRecordWithUnicode();

echo mb_strtolower($string);

完成!

PS:如果要确保数据库使用与PHP完全相同的编码,请使用utf8mb4作为字符集(并将utf8mb4_unicode_ci作为默认排序规则进行完美排序)或{{1 (二进制)数据类型。

PPS:使用您的数据库配置文件强制对所有字符串进行正确编码,而不是使用例如BLOB或类似的。

关于HTML表单

因为您在问题的评论中提出了问题。如何将数据发送到您的服务器与用户在其操作系统中设置的语言环境无关。它与客户端的浏览器有关。发送表单数据时,所有现代浏览器都默认为$mysqli->set_charset("utf8")。如果您担心某些客户可能使用完全破坏的浏览器,只需告诉他们您只接受utf-8。 Drupal在所有表单上都这样做。

utf-8

现在,所有浏览器都应对<!doctype html> <html> <body> <form accept-charset="UTF-8"> 中提交的数据进行编码。

答案 1 :(得分:1)

如果将çokGüŞelLl编码为UTF-8,则应获得以下字节:

var_dump( bin2hex('çokGüŞelLl') );
string(26) "c3a76f6b47c3bcc59e656c4c6c"

这是你必须做的检查。你也有这个:

utf8_encode($str)

您的字符串包含Ş,无法在ISO-8859-1中表示。

因此,无论出于什么原因,您必须将原始的UTF-8(存储在数据库中)转换为ISO-8859-1,我担心它会破坏您的数据。

答案 2 :(得分:0)

你是双重编码。首先,将数据库设置为UTF-8。这意味着您的数据现在是UTF-8编码的。然后在iconv-function上使用utf8_encode。但是您的输入已经是UTF-8。尝试从iconv中删除你的utf8_encode语句。