Cảnh báo: DOMDocument :: loadHTML (): htmlParseEntityRef: mong đợi ';' trong Thực thể,


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

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

echo $dom;

ném

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

Câu trả lời:


147

Để làm bay hơi cảnh báo, bạn có thể sử dụng 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

Tôi dám cá rằng nếu bạn nhìn vào nguồn của http://www.somesite.com/bạn, bạn sẽ tìm thấy các ký tự đặc biệt chưa được chuyển đổi sang HTML. Có thể như thế này:

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

Nên là

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

3
Chỉ để mở rộng về điều này, nếu ký tự & ngay cả trong văn bản và không phải là một thuộc tính HTML, thì nó vẫn cần được thoát thành & amp ;. Lý do trình phân tích cú pháp gặp lỗi là vì sau khi nhìn thấy & nó đang mong đợi một; để chấm dứt thực thể HTML.
Kyle

21
... và để mở rộng thêm, gọi htmlentities()hoặc tương tự trên chuỗi sẽ khắc phục sự cố.
Ben

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

Điều này không chính xác, hãy sử dụng điều này thay thế:

@$dom->loadHTML($html);

26
hoặc $ dom-> precisionErrorChecking = false;
Tjorriemorrie

6
Đây là một giải pháp tồi tệ vì bạn sẽ khiến các lỗi trên dòng này trở thành cơn ác mộng để gỡ lỗi. Giải pháp của @ Dewsworld tốt hơn nhiều.
Gerry

là những gì @cho?
Francisco Corrales Morales

2
Đây là một giải pháp rất bẩn và điều này sẽ không khắc phục được mọi thứ.
Mirko Brunner

1
Mặc dù câu trả lời của bạn sẽ giải quyết vấn đề, nhưng dòng "Điều này không chính xác", bản thân nó, không chính xác.
TecBrat

14

Có 2 lỗi: thứ hai là do $ dom không phải là chuỗi mà là một đối tượng và do đó không thể "echo". Lỗi đầu tiên là cảnh báo từ loadHTML, gây ra bởi cú pháp không hợp lệ của tài liệu html để tải (có thể là & (dấu và) được sử dụng làm dấu phân tách tham số và không được che dưới dạng thực thể có &).

Bạn bỏ qua và nhấn thông báo lỗi này (không phải lỗi, chỉ là thông báo!) Bằng cách gọi hàm với toán tử kiểm soát lỗi "@" ( http://www.php.net/manual/en/language.operators.errorcontrol. php )

@$dom->loadHTML($html);

12

Lý do gây ra lỗi nghiêm trọng của bạn là DOMDocument không có phương thức __toString () và do đó không thể lặp lại.

Có thể bạn đang tìm kiếm

echo $dom->saveHTML();

10

Bất kể echo (cần được thay thế bằng print_r hoặc var_dump), nếu một ngoại lệ được ném ra, đối tượng sẽ trống:

DOMNodeList Object
(
)

Giải pháp

  1. Đặt recoverthành true và strictErrorCheckingfalse

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. Sử dụng mã hóa thực thể của php trên nội dung của đánh dấu, đây là nguồn lỗi phổ biến nhất.


1
Ở giải pháp đầu tiên, bạn đã viết dom thay vì doc.
Máthé Endre-Botond

điều này có hiệu quả với tôi. Tôi chỉ thêm $ content = mb_convert_encoding ($ content, 'HTML-ENTITIES', 'UTF-8');
Jacek Pietal

8

thay thế đơn giản

$dom->loadHTML($html);

với ...

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;

thử đi


3

Một giải pháp khả thi khác là

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

Điều này sẽ không hoạt động. Theo php.net/manual/en/ Chức năng.htmlspecialchars.php , tất cả các ký tự đặc biệt html cũng được thoát. Lấy ví dụ về đoạn mã HTML này <span>Hello World</span>. Chạy nó vào htmlspecialcharssẽ tạo ra &lt;span&gt;Hello World&lt/span&gt;nó không phải là HTML nữa. DOMDocument :: loadHTML sẽ không coi nó là HTML nữa mà là một chuỗi.
Twisted Whisper

Điều này phù hợp với tôi:$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
Bartłomiej Jakub Kwiatek

3

Tôi biết đây là một câu hỏi cũ, nhưng nếu bạn muốn sửa các dấu '&' không đúng định dạng trong HTML của mình. Bạn có thể sử dụng mã tương tự như sau:

$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

Một giải pháp khả thi khác là, có thể tệp của bạn là tệp loại ASCII, chỉ cần thay đổi loại tệp của bạn.


-1

Ngay cả sau khi này, mã của tôi vẫn hoạt động tốt, vì vậy tôi chỉ xóa tất cả các thông báo cảnh báo với câu lệnh này ở dòng 1.

<?php error_reporting(E_ERROR); ?>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.