Avertissement: DOMDocument :: loadHTML (): htmlParseEntityRef: expecting ';' dans Entité,


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

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

echo $dom;

jette

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

Réponses:


147

Pour évaporer l'avertissement, vous pouvez utiliser 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

Je parierais que si vous regardiez la source, http://www.somesite.com/vous trouveriez des caractères spéciaux qui n'ont pas été convertis en HTML. Peut-être quelque chose comme ça:

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

Devrait être

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

3
Juste pour développer cela, si le caractère & est même dans du texte et non dans un attribut HTML, il doit quand même être échappé à & amp ;. La raison pour laquelle l'analyseur lance l'erreur est qu'après avoir vu un &, il attend un; pour terminer l'entité HTML.
Kyle

21
... et pour développer davantage, appeler htmlentities()ou similaire sur la chaîne résoudra le problème.
Ben

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

Ceci est incorrect, utilisez ceci à la place:

@$dom->loadHTML($html);

26
ou $ dom-> strictErrorChecking = false;
Tjorriemorrie

6
C'est une solution terrible car vous ferez des erreurs sur cette ligne un cauchemar à déboguer. La solution de @ Dewsworld est bien meilleure.
Gerry

à quoi ça sert @?
Francisco Corrales Morales

2
C'est une solution très sale et cela ne réglera pas tout.
Mirko Brunner

1
Bien que votre réponse contournera le problème, la ligne «Ceci est incorrect» est elle-même incorrecte.
TecBrat

14

Il y a 2 erreurs: la seconde est que $ dom n'est pas une chaîne mais un objet et ne peut donc pas être "écho". La première erreur est un avertissement de loadHTML, causé par une syntaxe invalide du document html à charger (probablement un & (esperluette) utilisé comme séparateur de paramètre et non masqué comme entité avec &).

Vous ignorez et supprimez ce message d'erreur (pas l'erreur, juste le message!) En appelant la fonction avec l'opérateur de contrôle d'erreur "@" ( http://www.php.net/manual/en/language.operators.errorcontrol. php )

@$dom->loadHTML($html);

12

La raison de votre erreur fatale est que DOMDocument n'a pas de méthode __toString () et ne peut donc pas être renvoyé.

Vous recherchez probablement

echo $dom->saveHTML();

10

Indépendamment de l'écho (qui devrait être remplacé par print_r ou var_dump), si une exception est levée, l'objet doit rester vide:

DOMNodeList Object
(
)

Solution

  1. Défini recoversur true et strictErrorCheckingsur false

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. Utilisez le codage d'entité de php sur le contenu du balisage, qui est une source d'erreur la plus courante.


1
Sur la première solution, vous avez écrit dom au lieu de doc.
Máthé Endre-Botond

cela a fonctionné pour moi J'ai seulement ajouté $ content = mb_convert_encoding ($ content, 'HTML-ENTITIES', 'UTF-8');
Jacek Pietal

8

remplacer le simple

$dom->loadHTML($html);

avec le plus robuste ...

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;

essaye ça


3

Une autre solution possible est

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

Cela ne fonctionnera pas. Selon php.net/manual/en/function.htmlspecialchars.php , tous les caractères spéciaux html sont également échappés. Prenons par exemple ce morceau de code HTML <span>Hello World</span>. L'exécution de cela htmlspecialcharsproduira &lt;span&gt;Hello World&lt/span&gt;ce qui n'est plus HTML. DOMDocument :: loadHTML ne le traitera plus comme du HTML mais comme une chaîne.
Twisted Whisper

Cela fonctionne pour moi:$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
Bartłomiej Jakub Kwiatek

3

Je sais que c'est une vieille question, mais si jamais vous ne voulez pas corriger les signes «&» mal formés dans votre HTML. Vous pouvez utiliser un code similaire à celui-ci:

$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

Une autre solution possible est, peut-être que votre fichier est de type ASCII, changez simplement le type de vos fichiers.


-1

Même après cela, mon code fonctionne correctement, je viens donc de supprimer tous les messages d'avertissement avec cette instruction à la ligne 1.

<?php error_reporting(E_ERROR); ?>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.