Wyłączanie ostrzeżeń podczas ładowania nie-dobrze uformowanego HTML przez DomDocument (PHP)

Muszę przeanalizować niektóre pliki HTML, jednak nie są one dobrze uformowane i PHP wypisuje Ostrzeżenia. Chcę uniknąć takiego debugowania/ostrzegania programowo. Proszę o radę. Dziękuję!

Kod:

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

To:

@$xmlDoc->loadHTML($fetchResult)

Może tłumić ostrzeżenia, ale jak Mogę programowo przechwytywać te ostrzeżenia?

Author: thomasrutter, 2009-07-19

4 answers

Możesz zainstalować tymczasowy program obsługi błędów za pomocą 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;
  }
}

Użycie:

// 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());
}
 14
Author: troelskn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-19 14:21:36

Call

libxml_use_internal_errors(true);

Przed przetworzeniem z $xmlDoc->loadHTML()

To mówi libxml2 aby nie wysyłać błędów i ostrzeżeń do PHP. Następnie, aby sprawdzić błędy i poradzić sobie z nimi samodzielnie, możesz skonsultować się z libxml_get_last_error() i/lub libxml_get_errors() Kiedy będziesz gotowy.

 194
Author: thomasrutter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-17 06:54:28

Aby ukryć Ostrzeżenia, musisz podać specjalne instrukcje libxml, które są używane wewnętrznie do parsowania:

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

The libxml_use_internal_errors(true) wskazuje, że masz zamiar obsłużyć błędy i ostrzeżenia siebie i nie chcesz, aby One bałagan wyjście skryptu.

To nie to samo co operator @. Ostrzeżenia są zbierane za kulisami, a następnie można je odzyskać za pomocą libxml_get_errors() W przypadku chęci wykonania logowanie lub zwrócenie listy spraw do rozmówcy.

Niezależnie od tego, czy używasz zebranych ostrzeżeń, zawsze należy wyczyścić kolejkę, wywołując libxml_clear_errors().

Zachowanie stanu

Jeśli masz inny kod, który używa libxml, może warto upewnić się, że Twój kod nie zmienia globalnego stanu obsługi błędów; w tym celu możesz użyć zwracanej wartości libxml_use_internal_errors(), aby zapisać poprzedni stan.

// 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);
 85
Author: Ja͢ck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 02:00:09

Ustawienie opcji "LIBXML_NOWARNING" & "LIBXML_NOERROR" działa również doskonale:

$dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
 2
Author: Joshua Ott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-03 06:50:30