DomDocument (PHP)에 의해 잘 구성되지 않은 HTML을로드 할 때 경고 비활성화


79

일부 HTML 파일을 구문 분석해야하지만 형식이 올바르지 않고 PHP가 경고를 출력합니다. 프로그래밍 방식으로 이러한 디버깅 / 경고 동작을 피하고 싶습니다. 조언하십시오. 감사합니다!

암호:

// create a DOM document and load the HTML data
$xmlDoc = new DomDocument;
// this dumps out the warnings
$xmlDoc->loadHTML($fetchResult);

이:

@$xmlDoc->loadHTML($fetchResult)

경고를 억제 할 수 있지만 프로그래밍 방식으로 경고를 캡처하려면 어떻게해야합니까?


이 솔루션을 시도 - 보인다 훨씬 쉽게 할 - stackoverflow.com/questions/6090667/...
마르신

형편없는 입력을 적절한 출력으로 변환하는 것이 비용을 지불하는 것입니다.) 복구 옵션은 매뉴얼에 있습니다 . 그것은 단지 부울입니다. $dom->saveHTML()문서 libxml이 $html입력을 시도하는 경우 어떤 종류인지 확인하기 만하면 됩니다 . 일반적으로 거의 비슷합니다.
Wrikken 2013

답변:


13

다음을 사용하여 임시 오류 처리기를 설치할 수 있습니다. set_error_handler

class ErrorTrap {
  protected $callback;
  protected $errors = array();
  function __construct($callback) {
    $this->callback = $callback;
  }
  function call() {
    $result = null;
    set_error_handler(array($this, 'onError'));
    try {
      $result = call_user_func_array($this->callback, func_get_args());
    } catch (Exception $ex) {
      restore_error_handler();        
      throw $ex;
    }
    restore_error_handler();
    return $result;
  }
  function onError($errno, $errstr, $errfile, $errline) {
    $this->errors[] = array($errno, $errstr, $errfile, $errline);
  }
  function ok() {
    return count($this->errors) === 0;
  }
  function errors() {
    return $this->errors;
  }
}

용법:

// create a DOM document and load the HTML data
$xmlDoc = new DomDocument();
$caller = new ErrorTrap(array($xmlDoc, 'loadHTML'));
// this doesn't dump out any warnings
$caller->call($fetchResult);
if (!$caller->ok()) {
  var_dump($caller->errors());
}

10
상황에 대해 많은 과잉 살인처럼 보입니다. PHP의 libxml2 함수를 참고하십시오.
thomasrutter

좋은 지적이야, 토마스. 이 답변을 쓸 때 이러한 기능에 대해 몰랐습니다. 내가 착각하지 않으면 내부적으로 똑같은 일을합니다.
troelskn

1
이 경우에도 동일한 효과가 있습니다. 예, 다른 수준에서 수행되었지만 위의 솔루션을 사용하면 PHP 오류가 생성되지만 억제되지만 저의 경우에는 PHP 오류가되지 않습니다. 나는 개인적으로 @ 또는 set_error_handler ()를 통해 PHP 오류를 억제하는 것이 포함되어 있다면 잘못된 방법이라고 생각합니다. 그래도 내 의견입니다. PHP 오류와 예외는 완전히 다릅니다. try {} catch () {}를 사용하는 것이 좋습니다.
thomasrutter

2
libxml_use_internal_errorsPHP의 오류 처리기에 연결되는 버그 보고서를 본 것 같습니다 .
troelskn

사람들 이이 답변을지나 아래의 더 나은 답변으로 스크롤하기를 바랍니다.
thomasrutter


94

경고를 숨기려면 libxml내부적으로 구문 분석을 수행하는 데 사용되는 특수 지침을 제공 해야합니다.

libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();

libxml_use_internal_errors(true)당신이 오류와 경고를 직접 처리 할거야 당신은 스크립트의 출력까지 혼란에 원하지 않는 것을 나타냅니다.

이것은 @운영자 와 동일하지 않습니다 . 경고는 배후에서 수집되며 libxml_get_errors()로깅을 수행하거나 문제 목록을 호출자에게 반환하려는 경우 사용하여 검색 할 수 있습니다 .

수집 된 경고를 사용하는지 여부에 관계없이 항상을 호출하여 대기열을 지워야합니다 libxml_clear_errors().

국가 보존

사용 libxml하는 다른 코드가있는 경우 코드가 오류 처리 의 전역 상태를 변경하지 않는지 확인하는 것이 좋습니다 . 이를 위해 반환 값 libxml_use_internal_errors()을 사용하여 이전 상태를 저장할 수 있습니다 .

// modify state
$libxml_previous_state = libxml_use_internal_errors(true);
// parse
$dom->loadHTML($html);
// handle errors
libxml_clear_errors();
// restore
libxml_use_internal_errors($libxml_previous_state);

2
@Greeso : 이전 값으로 설정됩니다 . 이는 전 세계적으로 다른 코드에 대해 구성되었을 수 있으며 나중에 FALSE설정하면 FALSE해당 설정이 파괴된다는 개념에 의해 수행됩니다 . 이전 반환 값을 사용하면 $libxml_previous_state원래 구성이이 장소 요구에 독립적으로 복원되었으므로 잠재적 인 부작용이 방지됩니다. libxml_use_internal_errors()는 일부 돌봐 가치가 그래서 설정은 글로벌입니다.
hakre

이미 libxml 오류가 보류중인 경우이 오류가 발생하지 않을까요?
cHao

@cHao 당신이 빈 슬레이트로 시작한다고 가정하는 것이 합리적이지 않습니까? :)
Ja͢ck

@ Ja͢ck : 아니요. 이전에를 호출 libxml_use_internal_errors(true)한 경우 발생한 오류를 처리하기 위해 대기 중일 수 있습니다.
cHao

23

"LIBXML_NOWARNING"및 "LIBXML_NOERROR"옵션 설정도 완벽하게 작동합니다.

$dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.