在将字符串保存到 UTF-8 中的 MySQL 时遇到问题


Having trouble saving strings to MySQL in UTF-8

我在编码某个文件时遇到问题。在我的php程序中,我得到一个txt文件。使用 foreach 并从该文件中获取每一行并做一个表,接下来我尝试将这些数据放入我的数据库中,插入后我在数据库中没有波兰字母。我的数据库,表和所有字段都有一个utf8_unicode_ci,当我使用phpmyadmin进行插入时,所有字母都是正常的。我尝试使用detect_encoding($row(,它检测ASCII解码。如何将波兰语字母插入我的数据库?请帮忙。

我的数据库连接:

try{
  $dbh = new PDO('mysql:dbname=google;host=localhost;','root','');  
  $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
  $dbh -> query ('SET NAMES utf8');
  $dbh -> query ('SET CHARACTER_SET utf8_unicode_ci');}

我尝试

$url = mb_convert_encoding($url,'UTF-8',mb_detect_encoding($url));

$url = Encoding::toUTF8($url);

和 OFC 图标还有其他想法吗?

在我的插入中一切正常,这是一个示例:

PDOStatement Object ( [queryString] => insert into `site` values ("","meblegdańsk.pl","1") ) 

我怀疑mb_detect_encoding((不像你想象的那样工作:

字符串 mb_detect_encoding ( 字符串 $str [, 混合 $encoding_list = mb_detect_order(( [, 布尔 $strict = 假 ]] (

如果省略第二个参数,则通常会在两个编码之间进行选择:

Array
(
    [0] => ASCII
    [1] => UTF-8
)

最后,您询问波兰语文本是 ASCII 还是 UTF-8,并将结果转换为 UTF-8。问题在于:

  • ASCII 是 UTF-8 的子集。从 ASCII 转换为 UTF-8 永远不会更改您的输入数据。
  • ASCII 不能对波兰语字符进行编码。

很难说为什么在没有示例数据的情况下获取ASCII作为输出 - 如果文本明显不是 UTF-8,PHP 可能默认为 ASCII,但将严格的编码检测标志设置为 false 无济于事。

我建议你重新思考为什么首先需要检测编码。如果应用程序不要求输入文件采用某些编码,并且无法更改该要求,我建议您编译波兰语文本中的典型编码列表,并用它馈送mb_detect_encoding()

顺便说一句,设置连接编码的推荐方法是DSN中的charset参数:

$dbh = new PDO('mysql:dbname=google;host=localhost;charset=utf8','root','');  

您的 mysql 查询是错误的。它是SET CHARACTER SET utf8_unicode_ci(注意空格而不是SETCHARACTER之间的下划线。这可能是导致您出现问题的最可能原因。

在一些奇怪的MySQL配置上,你可能需要设置其他字符编码相关的东西(但你通常不会,所以不要不必要地弄乱这些(: http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html

顺便说一下,这不会单独工作(除非您先使用mb_detect_order(:

$url = mb_convert_encoding($url,'UTF-8',mb_detect_encoding($url));

如果您想将 latin2 字符转换为 utf-8,但如果它们已经是 utf-8,则不要管它们,您应该这样做:

$url = mb_convert_encoding($url, 'UTF-8',array ('UTF-8', 'ISO-8859-2'));
// or
mb_detect_order(array ('UTF-8', 'ISO-8859-2'));
$url = mb_convert_encoding($url,'UTF-8',mb_detect_encoding($url));

如果您以前已经使用过这样的mb_detect_order(),请道歉。给其他人的注意事项:ISO-8859-2应该替换为您希望找到的任何其他编码,这可能取决于您使用的语言。在大多数西欧国家,ISO-8859-1 是通常使用的 1 字节字符编码。

无论如何,这允许检查给定的字符串是否是有效的 UTF-8(因此不会更改它(,或者如果它不是有效的 UTF-8,它假设它是 ISO-8859-2 并对其进行转换。顺序很重要,因为每个字符串都是有效的 ISO-8859-2,您将永远无法"回退"到 UTF-8。当你说ASCII时,我也假设你的意思是ISO-8859-2(它们不是一回事(。

另外,为了使我的答案完整,我还想提醒您,您应该确保表中的每一列也设置为使用 utf8 编码。