信息发布→ 登录 注册 退出

PHP如何解析RSS或Atom feed的XML

发布时间:2026-01-09

点击量:
最可靠方式是用 SimpleXML 配合 libxml 容错处理:先调用 libxml_use_internal_errors(true),再用 simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NONET | LIBXML_NOWARNING),最后 libxml_clear_errors()。

PHP 解析 RSS 或 Atom feed 的 XML,最可靠的方式是用 SimpleXML 配合 libxml 的容错处理——不是所有 feed 都严格符合规范,直接 simplexml_load_string() 容易报错中断。

为什么 simplexml_load_string() 常失败?

RSS/Atom feed 常含以下问题:XML declaration 编码声明不匹配、BOM 字节、命名空间混用、HTML 实体未转义、CDATA 块嵌套非法字符。默认调用会因 DOMDocument::loadXML() 的严格解析而抛出警告或返回 false

  • 必须先用 libxml_use_internal_errors(true) 抑制错误
  • 再用 simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA | LIBXML_NONET | LIBXML_NOWARNING)
  • LIBXML_NONET 防止解析器尝试加载外部 DTD(安全且提速)
  • 解析后记得调用 libxml_clear_errors() 避免污染后续 XML 操作

如何统一处理 RSS 2.0 和 Atom 1.0 的结构差异?

RSS 用 包裹条目,Atom 用 ;条目标签分别是 。别硬写两套逻辑,用命名空间 + XPath 更稳:

if ($xml->getName() === 'rss') {
    $items = $xml->channel->item;
} elseif ($xml->getName() === 'feed' && $xml->getNamespaces()) {
    $atom = $xml->getNamespaces()[''];
    $items = $xml->xpath('//entry');
} else {
    $items = $xml->xpath('//item | //entry');
}

注意:$xml->getNamespaces() 返回空数组 ≠ 没命名空间,Atom 常用默认命名空间(xmlns="http://www.w3.org/2005/Atom"),此时需显式传入 '' 键取值。

提取标题、链接、发布时间时容易踩哪些坑?

字段名看似一致,实际分布混乱:

  • RSS 的 是字符串,需用 strtotime() 转时间戳;Atom 的 是 ISO 8601 格式,可用 DateTime::createFromFormat() 或直接传给 new DateTime()
  • 链接字段:RSS 用 (可能为文本内容或属性 href),Atom 必须查 href 属性
  • 内容字段:RSS 多用 (需注册命名空间),Atom 用 ,且可能含 type="html" 属性

建议封装一个 getSafeText($node, $tagName) 函数,内部用 ->__toString() + trim() + htmlspecialchars_decode() 统一清理。

要不要用第三方库?比如 php-feed-reader

小项目够用,但要注意:php-feed-reader 内部仍基于 SimpleXML,只是封装了命名空间和字段映射。它对 malformed feed 的容错没比手写强多少,反而增加一层抽象导致调试困难。真正省心的场景只有两个:需要自动发现 feed 链接(从 HTML 提取),或要同时支持 JSON Feed。否则,20 行以内手写解析更可控。

复杂点永远在 feed 源本身——同一个站点今天发标准 RSS,明天加个自定义命名空间字段,或者把 写成 。别指望一次解析适配所有源,留好 fallback 字段和日志记录才是关键。

标签:# 字符串  # 装了  # 第三方  # 能为  # 报错  # 自定义  # 要用  # 才是  # 发布时间  # 最可靠  # 再用  # atom  # http  # href  # bom  # channel  # php  # simpleXML  # Libxml  # xml  # date  # 封装  # 命名空间  # 为什么  # lsp  # 字节  # 编码  # node  # json  # js  # html  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!