提问人:Math 提问时间:8/4/2023 最后编辑:A.LMath 更新时间:8/4/2023 访问量:58
simplexml_load_file 和 simplexml_load_string 以不同的编码返回相同的数据
simplexml_load_file and simplexml_load_string return the same data with different encoding
问:
尝试从 URL 解析 UTF-8 RSS 提要,我首先尝试了这个:
$flux = simplexml_load_file("https://mamanslouves.com/feed");
foreach($flux->channel->item as $Item){
$title = $Item->title;
echo $title;
}
此代码有效,但包含重音符号 (éèà) 的标题将转换为另一个字符集。 以下代码似乎解决了该问题:
$raw = file_get_contents("https://mamanslouves.com/feed");
$flux = simplexml_load_string($raw);
foreach($flux->channel->item as $Item){...}
我想知道为什么。
答:
0赞
KIKO Software
8/4/2023
#1
通过讨论,我在评论中与 MarkusZeller 进行了讨论,我认为答案应该包含 2 个组成部分。
首先,我们需要查看您正在使用的 URL。它不是您最终下载的文件的 URL。在浏览器开发人员工具的“网络”选项卡中查看一下,如下所示:
首先,在下载 RSS 源本身之前,有两个永久重定向 (301)。一切都经过编码,XML 甚至您下载的文件。唯一不是的是第一个重定向,它是编码的。您可以通过检查网络选项卡中的标头来查看这一点。UTF-8
UTF-8
iso-8859-1
然后我们需要考虑什么。它需要弄清楚它下载的文件的编码。它可以从许多位置获取编码:重定向的 HTTP 标头、源的 HTTP 标头或 XML 内容。现在很清楚,它使用它遇到的第一件事:第一个重定向的 HTTP 标头,上面写着 .所以,真正被解读为什么,从那里开始一切都出错了。然后将误读的字符转换为 ,但正如您所看到的,这毫无意义。simplexml_load_file()
iso-8859-1
UTF-8
iso-8859-1
UTF-8
为了证明第一次重定向中的错误搞砸了事情,您可以在没有重定向的情况下获取提要:charset
$flux = simplexml_load_file("https://mamanslouves.org/feed/");
foreach($flux->channel->item as $Item){
$title = $Item->title;
echo $title;
}
这确实返回了正常的重音字母。
之所以通过确实有效,是因为这个函数不关心 ,它只是给你二进制数据,然后被解释为一个字符串。正如马库斯所说。file_get_contents()
charset
UTF-8
评论
simplexml_load_file()
curl -vvv -i https://mamanslouves.com/feed
content-type: text/html; charset=iso-8859-1
encoding="UTF-8"
www.mamanslouves.org/feed
www.mamanslouves.org/feed/
Content-Type application/rss+xml; charset=UTF-8
content-type text/html; charset=iso-8859-1
simplexml_load_file("https://mamanslouves.org/feed/");
mamanslouves.com
charset