Php simplexml_将文件加载到数据库utf-8

Php simplexml_将文件加载到数据库utf-8,php,mysql,xml,encoding,utf-8,Php,Mysql,Xml,Encoding,Utf 8,我正在从API导入XML文件。我使用simplexml\u load\u file()加载文件。XML具有UTF-8编码。在某些元素的标题中,有特殊的字符accur,如“café”。如果我直接在浏览器中输出这些标题,我会很好地看到它们,但我将所有值存储在MySQL数据库中。尽管该表具有UTF-8编码,但值的存储方式类似于“PaardcafÔ。 我尝试了不同的编码,htmlentities等,但输出保持不变。即使编码没有从原始文件更改为存储到数据库中,为什么会出现这种情况 检查从PHP到数据库的

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

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

编码就像一条链,如果一条链断了,整个链都断了

由于编码是紧挨着实际数据的元信息,处理该数据的不同进程需要该元信息。如果一个进程具有错误的编码信息,则会出现错误的编码

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

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
这五个字节代表UTF-8格式的“
café
”字符:

c := 63
a := 61
f := 66
é := c3a9
就像内存中的二进制数据一样,它与数据库链接将字符传输到数据库服务器的方式类似:作为二进制数据

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

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

link: <data:latin1>  -- (re-encode) --> column: <data:utf8>
但是,对于相同的操作,如果数据库链接将携带数据编码为UTF-8的信息,则无需重新编码,因为该列的编码已经正确:

(utf8) 636166c3a9 ---> (utf8) 636166c3a9 
因此,让我们从最后两个示例中比较可读字符中的二进制UTF-8序列:

636166c383c2a9  := café
636166c3a9      := café
看起来眼熟吗?因此,即使PHP代码中的数据采用UTF-8编码,并且数据库列的编码为UTF-8,如果数据库链接携带错误的编码信息,编码仍然可能被破坏

那么,如何告诉数据库链接使用哪种编码呢?这取决于数据库驱动程序。您正在使用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\u charset
方法:

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

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

请看这里,这是一个很棒的东西,可以让您更清楚地了解编码的工作原理。谢谢你指出这一点。尽管这一切给了我更多关于未来问题的信息和知识,但Mysql连接似乎是用UTF-8设置的。所以我想我得再深入一点。感谢到目前为止的见解,我将继续寻找编码链在我的脚本中断裂的地方。这非常有助于我理解我的网站出了什么问题,谢谢。
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
$mysqli->set_charset('utf8');