【问题标题】:PHP Fatal error: Cannot use object of type simple_html_dom as arrayPHP 致命错误:不能使用 simple_html_dom 类型的对象作为数组
【发布时间】:2015-04-30 12:18:45
【问题描述】:

我正在使用simple_html_dom 开发网络抓取应用程序。我需要提取网页中的所有图像。以下是可能性:

  1. <img>标签图片
  2. 如果同一页面中有带有<style>标签的css。
  3. 如果存在带有<div> 或其他标签的内联样式的图像。

我可以使用以下代码抓取所有图像。

function download_images($html, $page_url , $local_url){

    foreach($html->find('img') as $element) {
        $img_url = $element->src;
        $img_url = rel2abs($img_url, $page_url);
        $parts   = parse_url($img_url);
        $img_path=  $parts['path'];
        $url_to_be_change = $GLOBALS['website_server_root'].$img_path;
        download_file($img_url, $GLOBALS['website_local_root'].$img_path);  
        $element->src=$url_to_be_change;            
    }

    $css_inline = $html->find("style");

    $matches = array();
    preg_match_all( "/url\((.*?)\)/", $css_inline, $matches, PREG_SET_ORDER );
    foreach ( $matches as $match )    {
        $img_url = trim( $match[1], "\"'" );
        $img_url = rel2abs($img_url, $page_url);
        $parts   = parse_url($img_url);
        $img_path=  $parts['path'];
        $url_to_be_change = $GLOBALS['website_server_root'].$img_path  ;
        download_file($img_url , $GLOBALS['website_local_root'].$img_path); 
        $html = str_replace($img_url , $url_to_be_change , $html );
    }

    return $html;
}

$html = download_images($html , $page_url , $dir); // working fine
$html = str_get_html ($html);
$html->save($dir. "/" . $ff);    

请注意,图片下载后我也在修改 HTML。

下载工作正常。但是当我试图保存 HTML 时,它会给出以下错误:

PHP 致命错误:不能使用 simple_html_dom 类型的对象作为数组

重要提示:如果我不使用 str_replace 和第二个循环,它的工作非常好。

致命错误:无法在第 1167 行的 /var/www/html/app/framework/cache/includes/simple_html_dom.php 中使用 simple_html_dom 类型的对象作为数组

【问题讨论】:

  • str_replace 调用中作为最后一个参数的 $html 是一个对象,而不是一个数组。 str_replace 显然不喜欢那样。您需要找出另一种方法来将该数据表示为一个数组,或者以某种方式对其进行重新处理。

标签: php simple-html-dom


【解决方案1】:

猜一猜

我在这里看到一个可能的错误:

$html = str_get_html($html);

看起来你将一个对象传递给函数 str_get_html(),而它接受一个字符串作为参数。让我们这样解决:

$html = str_get_html($html->plaintext);

我们只能猜测这段代码中 $html 变量的内容是什么。

猜二号

或者也许我们只需要在函数 download_images 中使用另一个变量来使您的代码在这两种情况下都正确:

function download_images($html, $page_url , $local_url){

    foreach($html->find('img') as $element) {
        $img_url = $element->src;
        $img_url = rel2abs($img_url, $page_url);
        $parts   = parse_url($img_url);
        $img_path=  $parts['path'];
        $url_to_be_change = $GLOBALS['website_server_root'].$img_path  ;
        download_file($img_url , $GLOBALS['website_local_root'].$img_path); 
        $element->src=$url_to_be_change;            
    }

    $css_inline = $html->find("style");

    $result_html = "";
    $matches = array();
    preg_match_all( "/url\((.*?)\)/", $css_inline, $matches, PREG_SET_ORDER );
    foreach ( $matches as $match )    {
        $img_url = trim( $match[1], "\"'" );
        $img_url = rel2abs($img_url, $page_url);
        $parts   = parse_url($img_url);
        $img_path=  $parts['path'];
        $url_to_be_change = $GLOBALS['website_server_root'].$img_path  ;
        download_file($img_url , $GLOBALS['website_local_root'].$img_path); 
        $result_html = str_replace($img_url , $url_to_be_change , $html );
    }

    return $result_html;
}

$html = download_images($html , $page_url , $dir); // working fine
$html = str_get_html ($html);
$html->save($dir. "/" . $ff);

解释:如果没有匹配(数组 $matches 为空),我们永远不会进入第二个循环,这就是为什么变量 $html 仍然具有与函数开头相同的值。当您尝试使用相同的变量代替需要两个不同变量的代码时,这是常见的错误。

【讨论】:

  • 第 1167 行:如果 ($this->size>0) $this->char = $this->doc[0];
  • 更新了我的答案。添加了另一种解决方案(请参阅 Guess №2 部分)。请告诉我这两个中的哪一个在所有情况下都有效。
  • 现在,它显示此错误。我看不到您的第二个解决方案。 PHP 致命错误:在 中的非对象上调用成员函数 save()
  • 啊,没关系,看看最后两行:$html = str_get_html ($html);这里我们将一个字符串保存到$html变量中,最后一个$html->save($dir. "/" . $ff);我们仍在尝试将其用作对象,但它现在是字符串!您应该修复它以使您的程序按预期工作,我无法帮助您,因为我只知道一小部分代码,而不是所有程序。希望这个解释能帮助你解决它。
  • 我已经尝试了第二种解决方案,旧错误已删除,但我无法保存 html。这是错误:致命错误:调用非对象中的成员函数保存()
【解决方案2】:

正如错误消息所述,您正在处理一个应该有一个数组的对象。 你可以尝试 tpyecasting 你的对象:

$array =  (array) $yourObject;

应该可以解决的。

【讨论】:

    【解决方案3】:

    我遇到了这个错误,我通过在函数末尾使用 (在我的情况下)return $html->save(); 解决了它。 我无法解释为什么两个具有不同变量名并在不同函数中作用域的实例会产生此错误。我想这就是“简单的 html dom”类的工作原理。

    为了清楚起见,尝试:$html->save(),然后再做任何其他事情

    我希望这些信息对某人有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多