【问题标题】:Call to a member function getAttribute() on a non-object in PHP?在 PHP 中调用非对象的成员函数 getAttribute()?
【发布时间】:2015-09-16 08:18:55
【问题描述】:

我正在尝试从 RSS 提要中获取图像。这是提要的结构:

<item>
<title>Title Here....</title>
<link>Link Here....</link>
<description>Description Here...</description>
<comments>Comments Here.</comments>
<pubDate>Tue, 15 Sep 2015 22:54:00 +0000</pubDate>
<guid isPermaLink="false">59551 at http://winsupersite.com</guid>
<media:thumbnail url="http://winsupersite.com/site-files/winsupersite.com/files/imagecache/thumb_img/uploads/2015/09/windowsrt81update3hero.png" />
<media:content url="http://winsupersite.com/site-files/winsupersite.com/files/uploads/2015/09/windowsrt81update3hero.png" medium="image">
</media:content>
</item>

这是我的 PHP 代码:

$rss = new DOMDocument();
$rss->load('http://winsupersite.com/rss.xml');
foreach ($rss->getElementsByTagName('item') as $node) {
   $title = $node->getElementsByTagName('title')->item(0)->nodeValue;
   $src   = $node->getElementsByTagName('thumbnail')->item(0)->getAttribute('url');
   $link  = $node->getElementsByTagName('link')->item(0)->nodeValue;
}

但我得到了错误:

在非对象上调用成员函数 getAttribute()

为什么会出现此错误? thumbnail 标签和url 属性都存在。

这是 $rss 上 var_dump 的结果:

object(DOMDocument)#1 (34) { 
["doctype"]=> NULL ["implementation"]=> string(22) "(object value omitted)" 
["documentElement"]=> string(22) "(object value omitted)" ["actualEncoding"]=> string(5) "utf-8" 
["encoding"]=> string(5) "utf-8" ["xmlEncoding"]=> string(5) "utf-8" ["standalone"]=> bool(true) 
["xmlStandalone"]=> bool(true) ["version"]=> string(3) "1.0" ["xmlVersion"]=> string(3) "1.0" ["strictErrorChecking"]=> bool(true)        ["documentURI"]=> string(31) "http://winsupersite.com/rss.xml" 
["config"]=> NULL ["formatOutput"]=> bool(false) ["validateOnParse"]=> bool(false) 
["resolveExternals"]=> bool(false) ["preserveWhiteSpace"]=> bool(true) ["recover"]=> bool(false) ["substituteEntities"]=> bool(false) ["nodeName"]=> string(9) "#document" ["nodeValue"]=> NULL ["nodeType"]=> int(9) ["parentNode"]=> NULL 
["childNodes"]=> string(22) "(object value omitted)" ["firstChild"]=> string(22) "(object value omitted)" ["lastChild"]=> string(22) "(object value omitted)" ["previousSibling"]=> NULL ["attributes"]=> NULL 
["ownerDocument"]=> NULL ["namespaceURI"]=> NULL ["prefix"]=> string(0) "" ["localName"]=> NULL ["baseURI"]=> string(31) "http://winsupersite.com/rss.xml" ["textContent"]=> string(27278) " SuperSite for Win........ Just text after this

【问题讨论】:

  • 那么$rss是什么?我们无法猜测,您必须告诉我们。将变量转储到日志文件中并查看。很可能创建对象只是失败了。你真的应该开始查看你的日志文件。您可以自己查看问题所在。
  • $rss 是一个变量。这是我从一开始的脚本,没有别的了。
  • 我问$rss内容是什么。倾倒它。见。
  • @arkascha 我已经更新了这个问题。
  • @SujataHulsurkar 检查下面的代码它将解决您的问题。

标签: php xml rss


【解决方案1】:

您只发布了 XML 的一部分,没有命名空间定义。您应该在祖先节点上有一个类似 xmlns:media="http://search.yahoo.com/mrss/" 的命名空间定义。

DOM 在解析 XML 时使用定义来解析前缀。带有前缀的元素和属性节点属于命名空间。你可以读到像{http://search.yahoo.com/mrss/}:thumbnail 这样的名字。命名空间允许混合使用相同节点名称的不同格式而不会引起冲突。

大多数 DOM 方法有两个版本,默认方法和带有后缀“NS”的变体,可识别命名空间。

$src = $node
  ->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail')
  ->item(0)
  ->getAttribute('url');

DOMNode::getElementsByTagName[NS]() 总是返回一个节点列表,这个列表可以为空。如果您访问空列表的第一项,则结果是错误的。为了使您的来源稳定,您需要在访问列表之前验证该列表是否包含项目。

或者您可以使用 Xpath 表达式。它们更强大,允许您从 DOM 获取节点列表或标量值。

$document = new DOMDocument();
$document->load($feedUrl);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('m', 'http://search.yahoo.com/mrss/');

foreach ($xpath->evaluate('//item') as $item) {
  var_dump(
    [
      'title' => $xpath->evaluate('string(title)', $item),
      'src' => $xpath->evaluate('string(m:thumbnail/@url)', $item),
      'link' => $xpath->evaluate('string(link)', $item)
    ]
  );
}

m:thumbnail/@url 将获取http://search.yahoo.com/mrss/ 命名空间中thumbnail 子节点的url 属性。 string() 会将节点转换为字符串,如果没有找到节点,它将返回一个空字符串。

【讨论】:

  • 第一种方法仍然显示错误,但使用 Xpath 的第二种方法有效。谢谢。 :)
  • 第一种方法如果节点不存在会抛出错误。在空节点列表上item(0) 将返回NULLNULL 不是对象,因此会出现错误。使用 Xpath,结果类型由表达式定义。即使列表为空且其他表达式返回标量,您也始终可以迭代列表。
【解决方案2】:

thumbnail 位于 media 命名空间内,因此您需要使用 getElementsByTagNameNS 来访问它。

你没有包含完整的 RSS 文档,但基本上你需要的命名空间应该在标题中,例如如果它是“http://search.yahoo.com/mrss/”,你的代码将是:

$src = $node->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail')->item(0)->getAttribute('url');

【讨论】:

  • 我仍然遇到同样的错误。这就是我所做的:`$src = $node->getElementsByTagNameNS('winsupersite.com/…;`
【解决方案3】:

检查一下,

$rss = new DOMDocument();
$rss->load('http://winsupersite.com/rss.xml');
foreach ($rss->getElementsByTagName('item') as $node) {
   $title = $node->getElementsByTagName('title')->item(0)->nodeValue;
   $src   = $node->getElementsByTagName('media:thumbnail')->item(0)->getAttribute('url');
   $link  = $node->getElementsByTagName('link')->item(0)->nodeValue;
}

它会解决你的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 2013-12-13
    相关资源
    最近更新 更多