【问题标题】:Unicode characters in MySQL returning different character code values in PHP and ASPMySQL 中的 Unicode 字符在 PHP 和 ASP 中返回不同的字符代码值
【发布时间】:2009-08-16 10:20:10
【问题描述】:

我有一个 MYSQL 数据库,它需要由 PHP 和 MySQL 脚本访问,这在大多数情况下都可以正常工作,但有一些“特殊”字符,例如双引号、撇号在 ASP 脚本中无法正确显示。

例如 MySQL 数据库来自 Drupal 安装并包含一个表,其中包含一个包含文本“双引号”的字段(引号是智能引号,但似乎不会在堆栈溢出时显示)。这在 php 脚本中显示得很好,但在 ASP 脚本中却没有。我已经在 PHP 和 ASP 中编写了一个简单的脚本来循环遍历字符串并打印字符代码,这里是输出:

PHP

“ 147
A 65
32
d 100
o 111
u 117
b 98
l 108
e 101
32
q 113
u 117
o 111
t 116
e 101
” 148

ASP

� 8220
A 65
 32
d 100
o 111
u 117
b 98
l 108
e 101
 32
q 113
u 117
o 111
t 116
e 101
� 8221

如您所见,双引号在 PHP 和 ASP 中显示为不同的字符,而 ASP 的显示不正确。

我正在使用标准 Drupal 安装和 PHP 5 在 Windows 机器上运行 MySQL 5。ASP 使用 MySQL ODBC 3.51 驱动程序,除了打开连接并运行之外,我没有在 PHP 或 ASP 中运行任何其他命令选择语句。

编辑这里要求的是asp脚本

Dim strConn, objConn, objRS, strQ
Dim i, strBody

strConn = "DRIVER={MySQL ODBC 3.51 Driver}; SERVER=" & strDBServer & "; DATABASE=studential; UID=" & strDBUser & ";PASSWORD=" & strDBPass & "; OPTION=3"

Set objConn = Server.CreateObject("ADODB.Connection")     
objConn.Open(strConn)

strQ = "select body from drupal_node_revisions where nid = 261"
Set objRS = objConn.Execute(strQ)

strBody = objRS("body")

For i = 1 To len(strBody)       
    Response.write(Mid(strBody, i, 1) & " " & AscW(Mid(strBody, i, 1))  & "<br />")
Next

objRS.Close
objConn.Close

Set objRS = Nothing
Set objConn = Nothing

进一步编辑

在下面的行中用 Asc 替换 AscW 时:

Response.write(Mid(strBody, i, 1) & " " & AscW(Mid(strBody, i, 1))  & "<br />")

字符代码现在匹配,但引号字符仍然显示不正确。我的页面包含 utf-8 字符集标记,因此很可能在此之前没有使用 utf-8 编码 - 知道它可能是什么或如何修复它?

感谢您的帮助,

汤姆

【问题讨论】:

    标签: php mysql unicode asp-classic utf-8


    【解决方案1】:

    这里似乎发生了几件事:

    我将假设在数据库中,表 drupal_node_revisions 中的列体确实设置为 Unicode 字符集。此外,我假设它确实以代码点 U+201C 左双引号开始。

    现在,PHP 似乎正在连接到 Latin1 中的数据库。这会导致 MySQL 将正在读取的数据转换为 Windows-1252(MySQL 中的“Latin1”实际上是指 Windows-1252)。因此将第一个字符转换为单字节 147。然后当你从 PHP 输出这个时,我猜你没有指明网页的字符编码,这导致它默认为 Latin1,这(叹气)几乎所有浏览器将其视为 Windows-1252。因此,双引号正确显示,但实际上犯了两个错误,这将导致其他 Unicode 字符失败:

    1. 您需要在连接中执行SET NAMES utf8;,确保与 MySQL 的所有连接变量(共有三个!)都在 UTF-8 中工作。

    2. 您需要确保网页的内容类型指示 UTF-8 字符集。这可以通过元元素来完成:&lt;meta http-equiv="content-type" content="text/html;charset=utf-8"&gt;

    ASP 代码似乎以某种 Unicode 编码连接到数据库。这表示为表达式 AscW(Mid(strBody, i, 1)) 为第一个字符返回 8220。生成未知字符字形的输出中的问题再次是 HTML 页面的字符集可能已保留为默认值,而不是与 Unicode 兼容的编码。

    我对 ASP 了解得不够多,无法知道 Response.write() 方法如何确定要使用的字符集编码,或者它是否期望字符串已经被编码,所以我不知道如何确保该数据路径是 Unicode 干净的端到端。

    【讨论】:

      【解决方案2】:

      我遇到了完全相同的问题。事实证明,列在latin1_swedish_ci 排序规则中——它使用了扩展的ascii 符号(例如 的146)——.Net 转换为unicode 符号——\u0092——但这不是一个有效的代码。最终解决方案的灵感来自this SO answer

      res = Encoding.GetEncoding(1252).GetString(res.Select(c => (byte) c).ToArray());
      

      【讨论】:

        【解决方案3】:

        您的 ASP 脚本似乎在使用 Unicode - 8220 = 0x201C,即 Unicode“左双引号”。您可能会在屏幕上看到垃圾,因为您的 ASP 脚本没有输出此 unicode 字符串的有效编码,但我们必须查看代码才能确定原因。

        【讨论】:

        • 我已将 ASP 脚本添加到原始问题中 - 谢谢,Tom
        • AscW() 会给你 unicode char,我猜它正在转换输入 char 147 并转换为 unicode。如果你使用 Asc() 会发生什么?很难说,但我猜你的 ASP 脚本告诉浏览器它正在获取 UTF-8,而你正在传递 Latin1。
        • 嗨保罗,你是对的,当我用 Asc 替换它时,代码看起来是一样的。有什么想法我可能需要在脚本中更改以通过 utf-8 而不是 latin1?
        • 请参阅stackoverflow.com/questions/777144/…,了解如何在输出之前将 latin1/iso8859 转换为 UTF-8。
        • 我尝试设置代码页,这似乎修复了示例 - 我将在我的实际脚本中尝试它。谢谢,汤姆
        猜你喜欢
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 2018-07-04
        相关资源
        最近更新 更多