Warnung: DOMDocument :: loadHTML (): htmlParseEntityRef: erwartet ';' in Entität,

87
$html = file_get_contents("http://www.somesite.com/");

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

echo $dom;

wirft

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
gweg
quelle

Antworten:

146

Um die Warnung zu verdampfen, können Sie verwenden 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);
Tauwelt
quelle
92

Ich würde wetten, wenn Sie sich die Quelle http://www.somesite.com/ansehen, würden Sie Sonderzeichen finden, die nicht in HTML konvertiert wurden. Vielleicht so etwas:

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

Sollte sein

<a href="/script.php?foo=bar&amp;hello=world">link</a>
mattalxndr
quelle
3
Um dies zu erweitern: Wenn das Zeichen & gerade im Text und kein HTML-Attribut ist, muss es dennoch nach & amp; maskiert werden. Der Grund, warum der Parser den Fehler auslöst, liegt darin, dass nach dem Anzeigen eines & ein a erwartet wird. um die HTML-Entität zu beenden.
Kyle
21
... und um weiter zu expandieren, htmlentities()wird das Problem durch Aufrufen oder ähnliches auf der Zeichenfolge behoben.
Ben
56
$dom->@loadHTML($html);

Dies ist falsch. Verwenden Sie stattdessen Folgendes:

@$dom->loadHTML($html);
Maanas Royy
quelle
25
oder $ dom-> strictErrorChecking = false;
Tjorriemorrie
6
Dies ist eine schreckliche Lösung, da Sie Fehler in dieser Zeile zu einem Albtraum machen, den Sie debuggen müssen. @ Dewsworlds Lösung ist viel besser.
Gerry
Wofür ist das @?
Francisco Corrales Morales
2
Dies ist eine sehr schmutzige Lösung und dies wird nicht alles reparieren.
Mirko Brunner
1
Während Ihre Antwort das Problem umgeht, ist die Zeile "Dies ist falsch" selbst falsch.
TecBrat
14

Es gibt 2 Fehler: Der zweite ist, weil $ dom kein String, sondern ein Objekt ist und daher nicht "wiedergegeben" werden kann. Der erste Fehler ist eine Warnung von loadHTML, die durch eine ungültige Syntax des zu ladenden HTML-Dokuments verursacht wird (wahrscheinlich ein & (kaufmännisches Und), das als Parametertrennzeichen verwendet und nicht als Entität mit & maskiert wird).

Sie ignorieren und unterdrücken diese Fehlermeldung (nicht den Fehler, sondern nur die Meldung!), Indem Sie die Funktion mit dem Fehlerkontrolloperator "@" ( http://www.php.net/manual/en/language.operators.errorcontrol ) aufrufen . php )

@$dom->loadHTML($html);
user279583
quelle
12

Der Grund für Ihren schwerwiegenden Fehler ist, dass DOMDocument keine __toString () -Methode hat und daher nicht wiederholt werden kann.

Sie suchen wahrscheinlich

echo $dom->saveHTML();
Mike B.
quelle
10

Unabhängig vom Echo (das durch print_r oder var_dump ersetzt werden müsste) sollte das Objekt leer bleiben, wenn eine Ausnahme ausgelöst wird:

DOMNodeList Object
(
)

Lösung

  1. Auf recovertrue und strictErrorCheckingfalse setzen

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
  2. Verwenden Sie die Entitätscodierung von PHP für den Inhalt des Markups, was eine der häufigsten Fehlerquellen ist.

Lorenz Lo Sauer
quelle
1
Bei der ersten Lösung haben Sie dom anstelle von doc geschrieben.
Máthé Endre-Botond
das hat bei mir funktioniert Ich habe nur $ content = mb_convert_encoding hinzugefügt ($ content, 'HTML-ENTITIES', 'UTF-8');
Jacek Pietal
8

Ersetzen Sie die einfache

$dom->loadHTML($html);

mit dem robusteren ...

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;
    }
David Chan
quelle
8
$html = file_get_contents("http://www.somesite.com/");

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

echo $dom;

Versuche dies

nmwi22
quelle
3

Eine andere mögliche Lösung ist

$sContent = htmlspecialchars($sHTML);
$oDom = new DOMDocument();
$oDom->loadHTML($sContent);
echo html_entity_decode($oDom->saveHTML());
lastYorsh
quelle
Dies wird nicht funktionieren. Laut php.net/manual/en/function.htmlspecialchars.php werden auch alle HTML-Sonderzeichen maskiert . Nehmen Sie zum Beispiel diesen HTML-Code <span>Hello World</span>. Wenn Sie dies htmlspecialcharsausführen, &lt;span&gt;Hello World&lt/span&gt;wird mehr HTML erstellt. DOMDocument :: loadHTML behandelt es nicht mehr als HTML, sondern als Zeichenfolge.
Twisted Whisper
Das funktioniert bei mir:$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
Bartłomiej Jakub Kwiatek
3

Ich weiß, dass dies eine alte Frage ist, aber wenn Sie jemals die fehlerhaften '&' Zeichen in Ihrem HTML korrigieren möchten. Sie können folgenden Code verwenden:

$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.
        }
    }
}
Nicolas Bouvrette
quelle
0

Eine andere mögliche Lösung ist, dass Ihre Datei möglicherweise vom ASCII-Typ ist. Ändern Sie einfach den Dateityp.

FRANK
quelle
-1

Auch danach funktioniert mein Code einwandfrei, daher habe ich gerade alle Warnmeldungen mit dieser Anweisung in Zeile 1 entfernt.

<?php error_reporting(E_ERROR); ?>
Satyam Gupta
quelle