【问题标题】:Warning: DOMDocument::loadHTML(): htmlParseEntityRef: expecting ';' in Entity,警告:DOMDocument::loadHTML(): htmlParseEntityRef: 期待 ';'在实体中,
【发布时间】:2009-11-06 03:40:26
【问题描述】:
$html = file_get_contents("http://www.somesite.com/");

$dom = new DOMDocument();
$dom->loadHTML($html);

echo $dom;

抛出

Warning: DOMDocument::loadHTML(): htmlParseEntityRef: expecting ';' in Entity,
Catchable fatal error: Object of class DOMDocument could not be converted to string in test.php on line 10

【问题讨论】:

    标签: php


    【解决方案1】:

    要消除警告,您可以使用libxml_use_internal_errors(true)

    // create new DOMDocument
    $document = new \DOMDocument('1.0', 'UTF-8');
    
    // set error level
    $internalErrors = libxml_use_internal_errors(true);
    
    // load HTML
    $document->loadHTML($html);
    
    // Restore error level
    libxml_use_internal_errors($internalErrors);
    

    【讨论】:

      【解决方案2】:

      我敢打赌,如果您查看 http://www.somesite.com/ 的源代码,您会发现尚未转换为 HTML 的特殊字符。也许是这样的:

      <a href="/script.php?foo=bar&hello=world">link</a>
      

      应该是

      <a href="/script.php?foo=bar&amp;hello=world">link</a>
      

      【讨论】:

      • 只是为了扩展这一点,如果 & 字符甚至在文本中而不是 HTML 属性,它仍然需要转义为 &。解析器抛出错误的原因是因为在看到 & 之后它期待 ;终止 HTML 实体。
      • ...为了进一步扩展,在字符串上调用htmlentities() 或类似名称将解决问题。
      【解决方案3】:
      $dom->@loadHTML($html);
      

      这是不正确的,改用这个:

      @$dom->loadHTML($html);
      

      【讨论】:

      • 或 $dom->strictErrorChecking = false;
      • 这是一个糟糕的解决方案,因为您将在此行上出错,成为调试的噩梦。 @Dewsworld 的解决方案要好得多。
      • @ 是什么意思?
      • 这是一个非常肮脏的解决方案,它不会解决所有问题。
      • 虽然您的答案可以解决问题,但“这是不正确的”这一行本身就是不正确的。
      【解决方案4】:

      有两个错误:第二个是因为 $dom 不是字符串而是一个对象,因此不能“回显”。第一个错误是来自 loadHTML 的警告,原因是要加载的 html 文档的语法无效(可能是一个 &(与号)用作参数分隔符,而不是用 & 屏蔽为实体)。

      您通过使用错误控制运算符“@”(http://www.php.net/manual/en/language.operators.errorcontrol.php)调用函数来忽略并抑制此错误消息(不是错误,只是消息!)

      @$dom->loadHTML($html);
      

      【讨论】:

        【解决方案5】:

        您的致命错误的原因是 DOMDocument 没有 __toString() 方法,因此无法回显。

        你可能正在寻找

        echo $dom->saveHTML();
        

        【讨论】:

          【解决方案6】:

          不管回显(需要用 print_r 或 var_dump 替换),如果抛出异常,对象应该保持为空:

          DOMNodeList Object
          (
          )
          

          解决方案

          1. recover 设置为true,将strictErrorChecking 设置为false

            $content = file_get_contents($url);
            
            $doc = new DOMDocument();
            $doc->recover = true;
            $doc->strictErrorChecking = false;
            $doc->loadHTML($content);
            
          2. 在标记的内容上使用 php 的实体编码,这是最常见的错误来源。

          【讨论】:

          • 在第一个解决方案中你写的是 dom 而不是 doc。
          • 这对我有用,我只添加了 $content = mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' );
          【解决方案7】:

          替换简单

          $dom->loadHTML($html);
          

          拥有更强大的...

          libxml_use_internal_errors(true);
          
          if (!$DOM->loadHTML($page))
              {
                  $errors="";
                  foreach (libxml_get_errors() as $error)  {
                      $errors.=$error->message."<br/>";
                  }
                  libxml_clear_errors();
                  print "libxml errors:<br>$errors";
                  return;
              }
          

          【讨论】:

            【解决方案8】:
            $html = file_get_contents("http://www.somesite.com/");
            
            $dom = new DOMDocument();
            $dom->loadHTML(htmlspecialchars($html));
            
            echo $dom;
            

            试试这个

            【讨论】:

              【解决方案9】:

              我知道这是一个老问题,但如果您想修复 HTML 中格式错误的“&”符号。你可以使用类似这样的代码:

              $page = file_get_contents('http://www.example.com');
              $page = preg_replace('/\s+/', ' ', trim($page));
              fixAmps($page, 0);
              $dom->loadHTML($page);
              
              
              function fixAmps(&$html, $offset) {
                  $positionAmp = strpos($html, '&', $offset);
                  $positionSemiColumn = strpos($html, ';', $positionAmp+1);
              
                  $string = substr($html, $positionAmp, $positionSemiColumn-$positionAmp+1);
              
                  if ($positionAmp !== false) { // If an '&' can be found.
                      if ($positionSemiColumn === false) { // If no ';' can be found.
                          $html = substr_replace($html, '&amp;', $positionAmp, 1); // Replace straight away.
                      } else if (preg_match('/&(#[0-9]+|[A-Z|a-z|0-9]+);/', $string) === 0) { // If a standard escape cannot be found.
                          $html = substr_replace($html, '&amp;', $positionAmp, 1); // This mean we need to escape the '&' sign.
                          fixAmps($html, $positionAmp+5); // Recursive call from the new position.
                      } else {
                          fixAmps($html, $positionAmp+1); // Recursive call from the new position.
                      }
                  }
              }
              

              【讨论】:

                【解决方案10】:

                另一个可能的解决方案是

                $sContent = htmlspecialchars($sHTML);
                $oDom = new DOMDocument();
                $oDom->loadHTML($sContent);
                echo html_entity_decode($oDom->saveHTML());
                

                【讨论】:

                • 这行不通。根据php.net/manual/en/function.htmlspecialchars.php,所有 html 特殊字符也都被转义了。以这段 HTML 代码&lt;span&gt;Hello World&lt;/span&gt; 为例。将其运行到htmlspecialchars 将产生&amp;lt;span&amp;gt;Hello World&amp;lt/span&amp;gt;,这不再是HTML。 DOMDocument::loadHTML 将不再将其视为 HTML,而是将其视为字符串。
                • 这对我有用:$oDom = new DOMDocument(); $oDom-&gt;loadHTML($sHTML); echo html_entity_decode($oDom-&gt;saveHTML());
                【解决方案11】:

                另一种可能的解决方案是,也许您的文件是 ASCII 类型的文件,只需更改文件的类型即可。

                【讨论】:

                  【解决方案12】:

                  即使在这之后我的代码运行良好,所以我只是在第 1 行使用此语句删除了所有警告消息。

                  <?php error_reporting(E_ERROR); ?>
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2012-09-01
                    • 2011-11-12
                    • 1970-01-01
                    • 2019-02-03
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-02-27
                    • 2014-06-22
                    相关资源
                    最近更新 更多