智能报价未正确转换为UTF8

Oba*_*bay 3 php xml mysql utf-8 character-encoding

我有一个PHP脚本,可以导入和解析XML文件并将数据保存到数据库中:

  • 数据库整理:utf8_general_ci,charset:utf8
  • Page的charset: utf-8
  • XML文件:ANSI,包含智能引号(来自MS Word)

因此,在导入期间,我会utf8_encode()在保存到数据库中并随后在页面上显示之前对XML文件中的文本执行操作.

但成功导入后,保存到DB中,

  • 数据库:智能引号保存为?字符(从CMD查看)
  • 页面:智能引号显示为框

有关为什么智能报价未正确转换的任何想法,即使在使用时utf8_encode()

编辑:

@Tomalak:XML​​文件实际上.txt没有XML声明(<?xml ... ?>),也没有根元素.我的脚本实际上添加了一个根元素,以便解析器工作:

utf8_encode('<article>' . file_get_contents($xmlfile) . '</article>');

好像我需要添加一个XML声明..?如果是这样,它应该怎么样?

Tom*_*lak 6

如果您的XML字符串(即文件内容)编码为UTF-8,则需要一个表示文件编码的XML声明.如果缺少XML声明,解析器将采用UTF-8.

只要您不使用"特殊"字符(即ASCII范围之外的任何字符),即使您的文件不是真正的 UTF-8编码,它也可以在没有声明的情况下工作.这是因为UTF-8与ASCII字节兼容.但是,只要在其中一个代码页上使用字符 - 比如"智能引号" - 它就会中断,因为它们由UTF-8中的不同字节表示.

在您的情况下,遗留编码中有一些文本文件,您可以使用根元素进行包装,以将它们转换为格式良好的XML.因此,您需要自己添加XML声明:

'<?xml encoding="Windows-1252"?><article>'.file_get_contents($xmlfile).'</article>'
Run Code Online (Sandbox Code Playgroud)

这样,您可以指示DOMDocument如何解释字符串中的字节.我假装Windows-1252你,因为你说ANSI并提到了卷曲的引号.

事实上,95%的时间这是人们真正的意思,即使在Linux上,即使他们说ISO-8859-1(或latin-1),这几乎是,但不完全相同的事情.

为了确保您可以在十六进制编辑器中打开文本文件,找到一些特殊字符并将其字节值与可疑编码进行比较.为了Windows-1252.对于卷曲引号,预期的字节值将是:

  • 147(0x93)
  • 148(0x94)

一旦声明了字符串中各个字节的含义,DOMDocument就可以理解它们并做正确的事情.

在数据库中,我强烈怀疑存在一些自动编码转换.我承认我对PHP/mySQL/Unicode集成的了解不够.