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
gweg
la source

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);
Dewsworld
la source
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>
mattalxndr
la source
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);
Maanas Royy
la source
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);
user279583
la source
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();
Mike B
la source
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.

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

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

echo $dom;

essaye ça

nmwi22
la source
3

Une autre solution possible est

$sContent = htmlspecialchars($sHTML);
$oDom = new DOMDocument();
$oDom->loadHTML($sContent);
echo html_entity_decode($oDom->saveHTML());
lastYorsh
la source
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.
        }
    }
}
Nicolas Bouvrette
la source
0

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

FRANC
la source
-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); ?>
Satyam Gupta
la source