Php 智能引号未正确转换为UTF8
我有一个PHP脚本,可以导入和解析XML文件,并将数据保存到数据库中:Php 智能引号未正确转换为UTF8,php,mysql,xml,utf-8,character-encoding,Php,Mysql,Xml,Utf 8,Character Encoding,我有一个PHP脚本,可以导入和解析XML文件,并将数据保存到数据库中: 数据库排序:utf8\u general\u ci,字符集:utf8 页面的字符集:utf-8 XML文件:ANSI,包含智能引号(来自MS Word) 因此,在导入过程中,我对XML文件中的文本执行utf8\u encode(),然后保存到数据库中,并随后显示在页面上 但是当成功导入并保存到DB中时 数据库:智能引号保存为?字符(从CMD查看) 页面:智能报价显示为方框 关于智能引号未正确转换的原因,即使使用utf
- 数据库排序:
,字符集:utf8\u general\u ci
utf8
- 页面的字符集:
utf-8
- XML文件:
,包含智能引号(来自MS Word)ANSI
utf8\u encode()
,然后保存到数据库中,并随后显示在页面上
但是当成功导入并保存到DB中时
- 数据库:智能引号保存为
字符(从CMD查看)?
- 页面:智能报价显示为方框
utf8\u encode()
,您有什么想法吗
编辑:
@Tomalak:XML文件实际上是.txt
,没有XML声明(
),也没有根元素。我的脚本实际上添加了一个根元素,以便解析器工作:
utf8\u编码(“”.file\u获取内容($xmlfile)。“”)代码>
似乎我需要添加一个XML声明。。?如果是这样,它应该是什么样子?它们被正确地转换,因为utf8\u encode完全执行它应该执行的操作,并将它们从输入流中删除
utf8_编码将ISO-8859-1中的文本转换为UTF-8编码。ISO-8859-1不包含smartquote字符。您的网页在浏览器中可能被视为MSWIN1252编码,其中确实包含smartquote字符,您通过调用utf8_encode强制PHP输入ISO-8859-1。这意味着只有以下字符才能进入数据库:
要解决这个问题,您必须确保网页本身采用UTF-8编码,并从代码中删除所有utf8_encode/utf8_decode语句。本页介绍如何正确使用UTF-8:如果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>'
”。对于卷曲引号,预期的字节值为:
“
147(0x93)
“
148(0x94)
一旦声明了字符串中各个字节的含义,DOMDocument
就可以理解它们,并做正确的事情
在DB中,我强烈怀疑有一些自动编码转换正在进行。我承认,我对PHP/mySQL/Unicode集成的了解还不够,不能肯定。是的,问题是有两种类型的智能引号
windows-1252和拉丁语-1
utf8_encode假设它是拉丁语-1,因此它得到的智能引号是错误的
如果我们知道输入数据是windows-1252,我们可以使用iconv进行转换
$string=iconv ( "Windows-1252" , "UTF-8" , $oldstring );
这是真正的答案。您能发布XML文件的XML声明(
)以及智能引号的字符代码(使用十六进制编辑器)吗?@Tomalak,我编辑了我的问题以回答您的评论您有错误。添加XML声明。文件获取内容($xmlfile)编码>并卸下utf8\u encode()
部件。然后用DOMDocument
解析结果字符串。只需确保编码
声明与文本文件中的字节匹配即可。(至少我认为应该是这样。)@Tomalak:如果你能把那条评论改写成答案,我会把它作为公认的答案:)不过有一个问题,你怎么知道应该使用“windows-1252”?因为我尝试了“iso-8859-1”,但它不起作用(我在Firefox中打开了XML(txt)文件,该文件报告为iso-8859-1)@Tomalak:另外,为什么不需要使用utf8编码将其转换为utf8,因为数据库是utf8格式的?十进制60处的拉丁1字符呢?这不是一个聪明的引号吗?@bvdb不,这不是一个聪明的引号,而是一个反勾号。Windows-1252字符集上的智能引号字符为145到148: