4

我正在使用 DOM 加载一堆 rss 提要,有时一个会 404 而不是生成文件。问题是网络服务器发送了一个 html 404 页面来代替预期的 xml 文件,因此使用以下代码:

$rssDom = new DOMDocument();
$rssDom->load($url);
$channel = $rssDom->getElementsByTagName('channel');
$channel = $channel->item(0);
$items = $channel->getElementsByTagName('item');

我收到这个警告:

Warning: DOMDocument::load() [domdocument.load]: Entity 'nbsp' not defined

随后出现此错误:

Fatal error: Call to a member function getElementsByTagName() on a non-object

通常,这段代码可以正常工作,但是在我得到 404 的情况下,它什么也做不了。我在 load 语句周围尝试了一个标准的 try-catch,但它似乎没有捕捉到它。

4

5 回答 5

8

您可以使用以下方法抑制解析错误的输出

libxml_use_internal_errors(true);

要检查返回的响应是否为 404,您可以$http_response_header在调用后检查DOMDocument::load()

例子:

libxml_use_internal_errors(true);
$rssDom = new DOMDocument();
$rssDom->load($url);
if (strpos($http_response_header[0], '404')) {
    die('file not found. exiting.');
}

另一种方法是使用file_get_contents然后检查响应标头,如果它不是 404,则使用DOMDocument::loadXml. 这将防止DOMDocument解析无效的 XML。

请注意,所有这些都假定服务器在响应中正确返回了 404 标头。

于 2012-05-01T09:33:37.840 回答
2

file_get_contents使用or手动加载 HTML curl(这允许您进行自己的错误检查),如果一切顺利,则将结果提供给DOMDocument::loadHTML.

这里有很多curl例子(例如看看这个,虽然它肯定不是最好的);获取您将使用的 HTTP 状态代码curl_getinfo

于 2012-05-01T09:30:24.790 回答
0

如果有人需要解决方案,这就像魅力:

$objDOM = new DOMDocument();
$loaded=@$objDOM->load(url);

if (!$loaded){
    //something went terribly wrong
} else {
    //this is going ok!!
}

这在我们通过“@”抑制警告时起作用,并且在发生错误时加载返回 true 或 false。

于 2013-01-24T10:02:33.863 回答
0

为了避免警告,您可以使用LIBXML_NOWARNING(注意:通常禁止警告不是一件好事)。

这里更重要的问题是致命错误:为避免这种情况,您应该检查文档是否已正确加载。为此,只需保存load()s 返回值并使用它:

$loaded = $rssDom->load($url, LIBXML_NOWARNING);
if($loaded){
    $channel = $rssDom->getElementsByTagName('channel');
    $channel = $channel->item(0);
    $items = $channel->getElementsByTagName('item');
}else{
    // show error-message or something like that
}
于 2012-05-01T09:33:58.643 回答
0

像这样:

$rssDom = new DOMDocument();
if($rssDom->load($url)) {
   $channel = $rssDom->getElementsByTagName('channel');
   $channel = $channel->item(0);
   $items = $channel->getElementsByTagName('item');
}
于 2012-05-01T09:36:12.620 回答