web-dev-qa-db-fra.com

Désactiver les avertissements lors du chargement de HTML non bien formé par DomDocument (PHP)

J'ai besoin d'analyser certains fichiers HTML, cependant, ils ne sont pas bien formés et PHP affiche les avertissements sur. Je veux éviter ce comportement de débogage/avertissement par programme. Veuillez le conseiller. Merci! Merci!

Code:

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

Cette:

@$xmlDoc->loadHTML($fetchResult)

peut supprimer les avertissements, mais comment puis-je capturer ces avertissements par programme?

73
Viet

Vous pouvez installer un gestionnaire d’erreurs temporaire avec 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;
  }
}

Usage:

// 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
troelskn

Appel

libxml_use_internal_errors(true);

avant le traitement avec avec $xmlDoc->loadHTML()

Cela indique à libxml2 de ne pas envoyer des erreurs et des avertissements via PHP. Ensuite, pour vérifier les erreurs et les gérer vous-même, vous pouvez consulter libxml_get_last_error () et/ou libxml_get_errors () lorsque vous êtes prêt.

205
thomasrutter

Pour masquer les avertissements, vous devez donner des instructions spéciales à libxml qui est utilisé en interne pour effectuer l'analyse:

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

libxml_use_internal_errors(true) indique que vous allez gérer les erreurs et les avertissements vous-même et que vous ne voulez pas qu'ils gâchent la sortie de votre script.

Ce n'est pas la même chose que l'opérateur @. Les avertissements sont collectés en arrière-plan et vous pouvez ensuite les récupérer en utilisant libxml_get_errors() au cas où vous souhaiteriez effectuer une journalisation ou renvoyer la liste des problèmes à l'appelant.

Que vous utilisiez ou non les avertissements collectés, vous devez toujours vider la file d'attente en appelant libxml_clear_errors() .

Préservation de l'état

Si vous avez un autre code qui utilise libxml, il peut être utile de vous assurer que votre code ne modifie pas l'état global de la gestion des erreurs; pour cela, vous pouvez utiliser la valeur de retour de libxml_use_internal_errors() pour enregistrer l'état précédent.

// 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);
87
Ja͢ck

La définition des options "LIBXML_NOWARNING" et "LIBXML_NOERROR" fonctionne également parfaitement:

$dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
7
Joshua Ott