Попередження: 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.
Kyle

21
... і для подальшого розширення виклик htmlentities()або подібний рядок вирішить проблему.
Бен

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

Це неправильно, використовуйте замість цього:

@$dom->loadHTML($html);

26
або $ dom-> strictErrorChecking = false;
Tjorriemorrie

6
Це жахливе рішення, оскільки ви робите помилки на цьому рядку, кошмаром для налагодження. Рішення @ Dewsworld набагато краще.
Gerry


2
Це дуже брудне рішення, і це не все виправить.
Мірко Бруннер

1
Хоча ваша відповідь допоможе вирішити проблему, рядок "Це неправильно" сам по собі неправильний.
TecBrat

14

Є 2 помилки: друга полягає в тому, що $ dom - це не рядок, а об'єкт, і тому не може бути "повтореним". Перша помилка - попередження від loadHTML, спричинене недійсним синтаксисом завантаження документа html (можливо, & (амперсанд), що використовується як роздільник параметрів і не маскується як сутність з &).

Ви ігноруєте та пригнічуєте це повідомлення про помилку (не помилку, а лише повідомлення!), Викликаючи функцію за допомогою оператора контролю помилок "@" ( 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. Встановіть 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.
Máthé Endre-Botond

це спрацювало для мене, я лише додав $ 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;

спробуйте це


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, а як рядок.
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); ?>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.