경고 : 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()위해 문자열을 호출 하거나 이와 유사한 방식으로 문제를 해결할 수 있습니다.
Ben

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

이것은 올바르지 않습니다. 대신 다음을 사용하십시오.

@$dom->loadHTML($html);

26
또는 $ dom-> strictErrorChecking = false;
Tjorriemorrie 2011

6
이 라인에서 오류를 디버깅하는 데 악몽이 될 것이기 때문에 이것은 끔찍한 솔루션입니다. @Dewsworld의 솔루션이 훨씬 좋습니다.
Gerry

무엇 @입니까?
Francisco Corrales Morales 2014

2
이것은 매우 더러운 솔루션이며 모든 것을 고치는 것은 아닙니다.
Mirko Brunner 2015

1
귀하의 답변으로 문제를 해결할 수 있지만 "이 내용이 잘못되었습니다"라는 줄 자체는 잘못되었습니다.
TecBrat

14

두 가지 오류가 있습니다. 두 번째는 $ dom이 문자열이 아니라 객체이므로 "반향"될 수 없기 때문입니다. 첫 번째 오류는로드 할 html 문서의 잘못된 구문으로 인해 발생하는 loadHTML의 경고입니다 (아마도 & (앰퍼샌드)가 매개 변수 구분 기호로 사용되고 &로 엔티티로 마스킹되지 않음).

오류 제어 연산자 "@"( 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. 설정 recovertrue로하고, strictErrorCheckingfalse로

    $content = file_get_contents($url);
    
    $doc = new DOMDocument();
    $doc->recover = true;
    $doc->strictErrorChecking = false;
    $doc->loadHTML($content);
    
  2. 가장 일반적인 오류 소스 인 마크 업의 내용에 PHP의 엔티티 인코딩을 사용합니다.


1
첫 번째 솔루션에서 doc 대신 dom을 작성했습니다.
Máthé Endre-Botond 2011

이것은 나를 위해 일했습니다. $ content = mb_convert_encoding ($ content, 'HTML-ENTITIES', 'UTF-8');
Jacek Pietal 2014 년

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>. 이것을 실행하면 더 이상 HTML이 아닌 것이 htmlspecialchars생성됩니다 &lt;span&gt;Hello World&lt/span&gt;. DOMDocument :: loadHTML은 더 이상 HTML로 처리하지 않고 문자열로 처리합니다.
Twisted Whisper

이것은 나를 위해 작동 :$oDom = new DOMDocument(); $oDom->loadHTML($sHTML); echo html_entity_decode($oDom->saveHTML());
Bartłomiej 야쿱 Kwiatek에게

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); ?>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.