如何在XMLReader中指定凭据访问带认证的XML Feed?
没问题!之前把用户名密码嵌在URL里的方式确实越来越多被服务器禁用了——一方面是安全风险(密码容易出现在服务器日志里),另一方面很多现代服务端和客户端都不再支持这种写法了。下面给你两种靠谱的方案,帮你搞定XMLReader的身份认证问题:
方案1:直接给XMLReader设置HTTP认证上下文
XMLReader的open()方法支持传入自定义的流上下文,我们可以在上下文里带上HTTP Basic认证的请求头,这样请求就会自动带上身份信息:
// 创建带认证信息的HTTP上下文 $authContext = stream_context_create([ 'http' => [ // 生成Basic认证的请求头 'header' => "Authorization: Basic " . base64_encode("你的用户名:你的密码"), 'timeout' => 15 // 可选,设置请求超时时间,避免卡壳 ] ]); // 初始化XMLReader并传入上下文 $reader = new XMLReader(); // 注意第四个参数就是我们创建的上下文 if (!$reader->open('http://mysite.com/feed.xml', null, LIBXML_NOBLANKS, $authContext)) { die("无法打开目标XML Feed,请检查地址或认证信息"); } // 接下来正常处理XML节点逻辑 while ($reader->read()) { if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'bio') { $bioContent = $reader->readInnerXml(); // 这里替换成你原本的处理逻辑 echo "获取到的bio内容:" . $bioContent; break; } } $reader->close();
方案2:用Curl先获取XML内容再传给XMLReader
如果你已经有Curl的代码基础,这种方式灵活性更高——尤其适合需要处理重定向、Digest认证或者自定义请求头的场景。先通过Curl完成认证并拿到XML内容,再交给XMLReader解析:
// 初始化Curl $ch = curl_init(); // 设置目标Feed地址 curl_setopt($ch, CURLOPT_URL, 'http://mysite.com/feed.xml'); // 让Curl返回内容而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 指定用Basic认证 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // 传入用户名和密码 curl_setopt($ch, CURLOPT_USERPWD, '你的用户名:你的密码'); // 可选:自动跟随重定向(如果Feed有跳转的话) curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 执行请求并获取XML内容 $xmlContent = curl_exec($ch); // 检查Curl请求是否出错 if (curl_errno($ch)) { die("Curl请求失败:" . curl_error($ch)); } curl_close($ch); // 将获取到的XML内容传给XMLReader解析 $reader = new XMLReader(); if (!$reader->xml($xmlContent, null, LIBXML_NOBLANKS)) { die("无法解析XML内容,请检查返回的内容是否正确"); } // 同样处理XML节点逻辑 while ($reader->read()) { if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'bio') { $bioContent = $reader->readInnerXml(); echo "获取到的bio内容:" . $bioContent; break; } } $reader->close();
额外提示
你之前遇到的XPath query failed for bio错误,很大概率是因为认证失败导致返回的不是预期的XML内容(比如返回了401错误页面的HTML),所以XPath找不到节点。建议先测试一下请求是否成功:比如用方案2的时候,先var_dump($xmlContent)看看返回的是不是正常的XML,确认认证没问题后再处理节点逻辑。
内容的提问来源于stack exchange,提问作者buck1112
相关产品推荐
相关产品推荐

