警告:DOMDocument :: loadHTML():htmlParseEntityRef: ';'が必要です エンティティでは、


88
$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

回答:


147

警告を蒸発させるために、あなたは使用することができます 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);

92

ソースを見ると、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>

3
これを拡張するために、&文字がHTML属性ではなくテキスト内にある場合でも、&amp;にエスケープする必要があります。パーサーがエラーをスローしている理由は、&を見た後、;を予期しているためです。HTMLエンティティを終了します。
カイル

21
...さらに展開するhtmlentities()には、文字列を呼び出すなどして問題を修正します。
ベン

56
$dom->@loadHTML($html);

これは正しくありません。代わりにこれを使用してください。

@$dom->loadHTML($html);

26
または$ dom-> strictErrorChecking = false;
Tjorriemorrie 2011

6
この行でエラーが発生するとデバッグが悪夢になるため、これはひどい解決策です。@Dewsworldのソリューションははるかに優れています。
ジェリー2013


2
これは非常に汚い解決策であり、これですべてが修正されるわけではありません。
Mirko Brunner 2015

1
あなたの答えは問題を回避しますが、「これは正しくありません」という行自体は正しくありません。
TecBrat 2017

14

2つのエラーがあります。2つ目は、$ domが文字列ではなくオブジェクトであるため、「エコー」できないためです。最初のエラーは、ロードするhtmlドキュメントの無効な構文が原因で発生するloadHTMLからの警告です(おそらく(アンパサンド)がパラメーター区切り文字として使用され、&でエンティティとしてマスクされていません)。

エラー制御演算子「@」(http://www.php.net/manual/en/language.operators.errorcontrol)を使用して関数を呼び出すことにより、このエラーメッセージ(エラーではなくメッセージのみ!)を無視して抑制します。 php

@$dom->loadHTML($html);

12

致命的なエラーの理由はDOMDocumentです__toString()メソッドがないため、エコーできないためです。

あなたはおそらく探しています

echo $dom->saveHTML();

10

エコー(print_rまたはvar_dumpに置き換える必要があります)に関係なく、例外がスローされた場合、オブジェクトは空のままである必要があります。

DOMNodeList Object
(
)

解決

  1. recovertrueに設定し、strictErrorCheckingfalseに設定します

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. 最も一般的なエラーソースであるマークアップのコンテンツにphpのエンティティエンコーディングを使用します。


1
最初の解決策では、docの代わりにdomを作成しました。
Máthéエンドレ-Botond

これは私にとってはうまくいきました。$ content = mb_convert_encoding($ content、 'HTML-ENTITIES'、 'UTF-8');を追加しただけです。
Jacek Pietal 2014

8

単純なものを置き換える

$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;

これを試して


3

別の可能な解決策は

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

これは機能しません。php.net/manual/en/function.htmlspecialchars.phpによると、すべてのhtml特殊文字もエスケープされます。このHTMLコードを例にとってみましょう<span>Hello World</span>。これを実行するhtmlspecialcharsと、&lt;span&gt;Hello World&lt/span&gt; HTMLではなくなったものがます。DOMDocument :: loadHTMLは、それをHTMLとしてではなく、文字列として扱います。
ツイストウィスパー

これは私のために働きます: $oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
パルトロミエヤクブKwiatek

3

これは古い質問ですが、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.
        }
    }
}

0

別の可能な解決策は、ファイルがASCIIタイプのファイルである可能性があり、ファイルのタイプを変更するだけです。


-1

この後でも、私のコードは正常に機能しているので、1行目のこのステートメントですべての警告メッセージを削除しました。

<?php error_reporting(E_ERROR); ?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.