Предупреждение: DOMDocument :: loadHTML (): htmlParseEntityRef: ожидая ';' в Entity,

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
gweg
источник

Ответы:

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);
Dewsworld
источник
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>
mattalxndr
источник
3
Чтобы расширить это, если символ & находится даже в тексте, а не в атрибуте HTML, его все равно нужно экранировать в & amp ;. Причина, по которой синтаксический анализатор выдает ошибку, заключается в том, что, увидев &, он ожидает; для завершения HTML-объекта.
Kyle
21
... и для дальнейшего расширения вызов htmlentities()или аналогичный вызов в строке устранит проблему.
Бен
56
$dom->@loadHTML($html);

Это неверно, используйте вместо этого:

@$dom->loadHTML($html);
Маанас Рой
источник
26
или $ dom-> strictErrorChecking = false;
Tjorriemorrie
6
Это ужасное решение, так как вы превратите ошибки в этой строке в кошмар для отладки. Решение @ Dewsworld намного лучше.
Джерри
для чего @?
Франсиско Корралес Моралес,
2
Это очень грязное решение, и оно не исправит всего.
Мирко Бруннер
1
Хотя ваш ответ поможет обойти проблему, строка «Это неверно» сама по себе неверна.
TecBrat
14

Есть 2 ошибки: вторая из-за того, что $ dom - это не строка, а объект, и поэтому его нельзя "повторить". Первая ошибка - это предупреждение от loadHTML, вызванное недопустимым синтаксисом загружаемого html-документа (возможно, & (амперсанд), который используется как разделитель параметров и не замаскирован как объект с помощью &).

Вы игнорируете и подавляете это сообщение об ошибке (не ошибку, а просто сообщение!), Вызывая функцию с оператором контроля ошибок «@» ( http://www.php.net/manual/en/language.operators.errorcontrol. php )

@$dom->loadHTML($html);
user279583
источник
12

Причина вашей фатальной ошибки в том, что DOMDocument не имеет метода __toString () и поэтому не может быть отображен эхом.

Вы, наверное, ищете

echo $dom->saveHTML();
Майк Б.
источник
10

Независимо от эха (которое необходимо заменить на print_r или var_dump), если выбрасывается исключение, объект должен оставаться пустым:

DOMNodeList Object
(
)

Решение

  1. Установите recoverзначение true и strictErrorCheckingfalse

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. Используйте кодировку объекта php для содержимого разметки, что является наиболее распространенным источником ошибок.

Лоренц Ло Зауэр
источник
1
В первом решении вы написали dom вместо doc.
Мате Эндре-Ботонд
это сработало для меня, я добавил только $ content = mb_convert_encoding ($ content, 'HTML-ENTITIES', 'UTF-8');
Jacek Pietal
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;

попробуй это

nmwi22
источник
3

Другое возможное решение:

$sContent = htmlspecialchars($sHTML);
$oDom = new DOMDocument();
$oDom->loadHTML($sContent);
echo html_entity_decode($oDom->saveHTML());
lastYorsh
источник
Это не будет работать. Согласно 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, а как строку.
Twisted Whisper
У меня это работает:$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
Бартломей Якуб Квятек
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); ?>
Сатьям Гупта
источник