MySQL中的Unicode字符在PHP和ASP中返回不同的字符代码值

时间:2009-08-16 10:20:11

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

我有一个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的引号无法正确呈现。

我在使用PHP 5的标准Drupal安装的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编码 - 任何想法可能是什么或我如何解决它?

感谢您的帮助,

汤姆

3 个答案:

答案 0 :(得分:2)

这里似乎有几件事情发生了:

我将假设在数据库中,表drupal_node_revisions中的列主体确实设置为Unicode字符集。此外,我假设它确实从代码点U + 201C LEFT DOUBLE QUOTATION MARK开始。

现在,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的字符集。这可以使用元元素:<meta http-equiv="content-type" content="text/html;charset=utf-8">

  3. 来完成

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

    我不太了解ASP知道Response.write()方法如何确定要使用的字符集编码,或者它是否希望字符串已经被编码,所以我无法弄清楚如何确保该数据路径是端到端的Unicode清理。

答案 1 :(得分:1)

我有完全一样的问题。原来,列是latin1_swedish_ci归类-它使用扩展的ascii符号(例如为146)-.Net转换为unicode符号-\u0092-但这不是有效的代码。最终解决方案的灵感来自this SO answer

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

答案 2 :(得分:0)

您的ASP脚本似乎使用Unicode - 8220 = 0x201C,这是Unicode“LEFT DOUBLE QUOTATION MARK”。你可能在屏幕上看到了垃圾,因为你的ASP脚本没有输出这个unicode字符串的有效编码,但是我们必须看到代码来确定原因。