simplexml_load_file到数据库utf-8

时间:2014-07-31 10:50:36

标签: php mysql xml encoding utf-8

我从API导入XML文件。我使用simplexml_load_file()来加载文件。 XML具有UTF-8编码。在一些元素的标题特殊字符accur,如“café”。如果我直接在浏览器中输出这些标题,我看到它们就好了,但我将所有值存储在MySQL数据库中。虽然该表具有UTF-8编码,但值的存储方式类似于“Paardcafé”。 我尝试了不同的enconding,htmlentities等,但输出保持不变。即使编码没有从原始文件更改为存储到数据库中,为什么会出现这种情况?

2 个答案:

答案 0 :(得分:1)

编码就像一个链条,如果一个链接断开,整个链断裂。

由于编码是实际数据旁边的元信息,因此使用该数据的不同进程需要具有该元信息。如果一个进程的编码信息错误,则会显示错误的编码。

在您的情况下,您有以下链:

API -> XML -> SimpleXMLElement -> PHP Variable -> Database Link -> Database Store

问题在于最后的部分,对于您已经检查过的API,XML,SimpleXMLElement和PHP变量,编码是正确的。左边是结尾部分:

PHP Variable -> Database Link -> Database Store
   *good*                            *bad*

如您所见,数据库链接介于两者之间。那么那里发生了什么?

数据库链接包含一些信息,其中从PHP传递的编码字符在被提供给数据库存储时被编码。

这是怎么样的?让我们在PHP代码中看到您的问题:

$word = "café";

假设这个PHP代码编码为UTF-8(当浏览器请求答案时,它也会在Stackoverflow上)。在计算机内存中,它存储为二进制数据。这是逐字节的,在这种情况下,如果您查看内存,您会看到类似这样的内容:

636166c3a9

这五个字节代表“café”字符为UTF-8:

c := 63
a := 61
f := 66
é := c3a9

与内存中的二进制数据一样,它类似于数据库链接如何将字符传输到数据库服务器:作为二进制数据。

所以链接的另一端需要知道如何解释这个二进制序列。为此,它需要知道编码,因为数据库需要将数据存储到您说它是UTF-8编码的列中。

因此,例如,如果数据库服务器通过数据库链接变成二进制字符数据,该数据库链接的编码与列所需的编码不同,则数据库服务器重新生成 - 将通过链接传递的二进制数据编码为将数据存储在列中所需的编码:

link: <data:latin1>  -- (re-encode) --> column: <data:utf8>

因此,假设数据库链接具有将字符编码为ISO-8859-1(拉丁语1)的信息,同时它发送二进制序列&lt; 636166c3a9&gt; ;从上面。该列需要有UTF-8。然后数据库服务器将重新编码该序列:

(latin1) 636166c3a9 ---> (utf8) 636166c383c2a9

然而,对于相同的操作,如果数据库链接将携带数据被编码为UTF-8的信息,则不需要重新编码,因为它已经在列的正确编码中:

(utf8) 636166c3a9 ---> (utf8) 636166c3a9 

因此,让我们从最后两个例子中比较可读字符中的二进制UTF-8序列:

636166c383c2a9  := café
636166c3a9      := café

看起来很熟悉?因此,即使PHP代码中的数据具有UTF-8编码,数据库列的编码也是UTF-8,如果数据库链接携带错误的编码信息,编码仍然可能被破坏。 / p>

那么如何告诉Database Link使用哪种编码?这取决于数据库驱动程序。你正在使用Mysql,所以你可能在PHP中使用PDO。对于PDO Mysql,您可以将 charset 参数添加到DSN,例如最后的“;charset=utf8”:

$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8", "my_user", "my_password");

或者,如果您使用的是Mysqli,请调用set_charset方法:

$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$mysqli->set_charset('utf8');

我希望这会让您更清楚这个问题,并向您展示如何更改设置。

答案 1 :(得分:0)

检查从PHP到数据库的连接编码。