首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP简单HTML Dom解析器在遍历空元素时发现()崩溃

PHP简单HTML Dom解析器在遍历空元素时发现()崩溃
EN

Stack Overflow用户
提问于 2013-03-26 05:18:48
回答 2查看 2.4K关注 0票数 2

我试图链接简单HTML DOM解析器 find()遍历HTML,但是当其中一个孩子缺席时,它似乎会崩溃。例如:

代码语言:javascript
复制
$obj = $page->find('#headings', 0)->find('h4', 0)->nodes[0];

如果find(‘# to’,0)或find('h4',0)返回null (即。如果元素不在HTML中,但如果所有元素都存在,则会成功。

有没有一种方法可以使上面的链返回null而不是崩溃的PHP?我考虑过修改simplehtmldom,但不确定如何修改。find()函数列在下面:

代码语言:javascript
复制
// find dom node by css selector
// Paperg - allow us to specify that we want case insensitive testing of the value of the selector.
function find($selector, $idx=null, $lowercase=false)
{
    return $this->root->find($selector, $idx, $lowercase);
}

编辑:(解决方案)

按照user1508519的建议,我创建了另一个nfind()函数。使用这种方法,PHP仍然会标记一个通知,如果一个null属性(与方法相反- find()方法在链接时返回一个空节点)在链的下游被引用,但是不会像使用find()时那样在没有解释的情况下崩溃。

代码语言:javascript
复制
// modified version of simple_html_dom->find() that will return an empty node instead of null when chained if an element is not found. simple_html_dom_node->nfind() must also be created for this to work.
function nfind($selector, $idx=null, $lowercase=false)
{
                $this->root->nfind($selector, $idx, $lowercase);
}

执行查找操作的实际代码可以在simple_html_dom_node-> find ()中找到,下面的函数应该放在simple_html_dom_node中,这样整个包才能正常工作(最后一行只修改-出于某种原因,包装原来的find()函数它和检查is_null似乎仍然会崩溃

代码语言:javascript
复制
//modifed version of simple_html_dom_node->find()
function nfind($selector, $idx=null, $lowercase=false)
{
    $selectors = $this->parse_selector($selector);
    if (($count=count($selectors))===0) return array();
    $found_keys = array();

    // find each selector
    for ($c=0; $c<$count; ++$c)
    {
        // The change on the below line was documented on the sourceforge code tracker id 2788009
        // used to be: if (($levle=count($selectors[0]))===0) return array();
        if (($levle=count($selectors[$c]))===0) return array();
        if (!isset($this->_[HDOM_INFO_BEGIN])) return array();

        $head = array($this->_[HDOM_INFO_BEGIN]=>1);

        // handle descendant selectors, no recursive!
        for ($l=0; $l<$levle; ++$l)
        {
            $ret = array();
            foreach ($head as $k=>$v)
            {
                $n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k];
                //PaperG - Pass this optional parameter on to the seek function.
                $n->seek($selectors[$c][$l], $ret, $lowercase);
            }
            $head = $ret;
        }

        foreach ($head as $k=>$v)
        {
            if (!isset($found_keys[$k]))
                $found_keys[$k] = 1;
        }
    }

    // sort keys
    ksort($found_keys);

    $found = array();
    foreach ($found_keys as $k=>$v)
        $found[] = $this->dom->nodes[$k];

    // return nth-element or array
    if (is_null($idx)) return $found;
    else if ($idx<0) $idx = count($found) + $idx;
    return (isset($found[$idx])) ? $found[$idx] : new simple_html_dom_node('');
}

再次感谢user1508519帮助我找到所需的解决方案,同时提供了一系列同样有效的替代方案!欢迎关于解决方案/潜在副作用的有效性的评论,或者如果任何人有进一步的投入,是否有一种更优雅的方法来实现这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-26 05:26:40

你为什么要用链子做这件事?如果每个调用为null,为什么不签入后续的检查?正如注释所述,不能对空对象进行操作。如果您正在执行foreach循环,它将消除对null检查的需要。

代码语言:javascript
复制
$obj = $page->find('#headings', 0);
if (!is_null($obj)) {
   $obj = $page->find('h4', 0);
   if (!is_null($obj))
       // ...continue...
}

编辑:

代码语言:javascript
复制
function find($selector, $idx=null, $lowercase=false)
{
    if (is_null($this->root->find($selector, $idx, $lowercase)))
    {
         die("error");
         // throw exception?
    } else // whatever

}

编写自己的包装函数,在内部调用simple的find。

喜欢

代码语言:javascript
复制
function wrapper($selector, $idx=null, $lowercase=false) {
    // yep 
}
票数 1
EN

Stack Overflow用户

发布于 2013-03-26 06:47:37

你可以这样做:

代码语言:javascript
复制
$obj = ($h4 = $page->find('#headings h4', 0)) ? $h4->nodes[0] : null;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15629891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档