通过php存储特殊字符(德语)SqlServer


Store special characters (german) SqlServer via php

我有一台fedora机器作为服务器,apache运行php5.3

脚本充当各种来源向我发送"消息"的入口页面。

php脚本的调用类似于:serverAddress/phpScript.php?message=MyMessage,然后通过PDO保存消息以连接到SqlServer2008db。

如果消息包含任何特殊字符(例如德语),如:üäß,那么在数据库中,我会得到一些胡言乱语,而不是正确的字符串:

数据库完全能够使用UTF-8-我可以连接和发送/检索德语字符,而不会与其他工具发生任何问题(而不是通过php)。

php脚本内部:

  • 如果我回显输入字符串,我会得到正确的字符串üäß
  • 如果我把它保存到一个文件中(记录输入),我会看到胡言乱语:

是什么导致了这种行为?我该怎么修

  • 启用了多字节(通过百胜安装php-mbstring,然后再启动apache)

  • 在我的php脚本的开头,我有:

mb_internal_encoding('UTF-8');mb_http_output('UTF-8');mb_http_input('UTF-8');mb_语言('uni');mb_regex_encoding('UTF-8');ob_start('mb_output_handler')
  • 根据我的理解,通过PDO处理mssql时的默认编码类型是UTF-8

新发展:

一位同事把我指给PDO_DBLIB页面(此时只能从缓存中看到),在那里我看到了$res->bindValue(':value', iconv('UTF-8', 'ISO8859-1', $value);

我用$res->bindParam(':text',iconv('UTF-8', 'ISO8859-1',$text));替换了所有的$res->bindParam(':text',$text);,一切正常:)。

mb_internal_encoding。。。。并且不再需要所有其他线路。

为什么它在使用ISO8859-1编码时有效

数据库可以处理特殊字符,甚至不支持Unicode集(UTF-8恰好是一种编码,特别是可变长度编码)。

字符集是数字和字符之间的映射。Unicode和ASCII是字符集的常见示例。Unicode表示符号映射到数字8364(实际上它使用代码点U+20AC)。UTF-8是编码Unicode码点的一种方式,用三个字节表示U+20AC0xE2 0x82 0xAC;UTF-16是Unicode码点的另一个编码,它总是使用两个字节:0x20AC(链接)。这两种编码都引用了Unicode目录中的同一个8364条目。

ASCII既是一个字符集,也是一种编码方案:ASCII字符集将数字从0到127映射到128个人类字符,ASCII编码需要一个字节。

永远记住,字符串是一个人类概念。它在计算机中由元组(byte_content, encoding)表示。假设您希望在数据库中存储Unicode字符串请注意:如果您只需要支持德语用户,就没有必要使用Unicode集。当您想在同一列中同时存储阿拉伯语、汉语、希伯来语和德语时,它很有用。MSSQLServer使用UCS-2对Unicode进行编码,对于声明为NCHARNVARCHAR的列(请注意N前缀)也是如此。因此,您的第一个操作将是检查目标列类型是否实际为nvarchar(或nchar)。

然后,让我们假设所有输入字符串在PHP脚本中都是UTF-8编码的。你想执行类似的东西

$stmt->bindParam(':text', $utf8_encoded_text);

根据文档,UTF-8是默认的字符串编码。我希望它足够智能,可以使用NVARCHAR,否则您可能需要使用额外的选项。

您同事的解决方案不存储Unicode字符串:它在ISO-8859-1空间中进行转换,然后将字节保存在简单CHARVARCHAR列中。不同的是,您将无法存储ISO-8859-1空间之外的字符(例如波兰语)

看看这篇关于"在Web应用程序中前后处理Unicode"的文章。到目前为止,这是我见过的关于这个主题的最好的文章之一。如果你遵循指南,问题仍然存在,那么你肯定知道这不是你的错。