85

我需要解析一些 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)

可以抑制警告,但如何以编程方式捕获这些警告?

4

4 回答 4

234

称呼

libxml_use_internal_errors(true);

在用 with 处理之前$xmlDoc->loadHTML()

这告诉 libxml2不要向 PHP 发送错误和警告。然后,要检查错误并自己处理它们,您可以在准备好时咨询libxml_get_last_error()和/或libxml_get_errors()

libxml_use_internal_errors(true);
$dom->loadHTML($html);
$errors = libxml_get_errors();
foreach ($errors as $error) {
    // handle the errors as you wish
}
于 2010-05-17T06:54:28.753 回答
98

要隐藏警告,您必须给出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);
于 2013-07-09T22:59:37.623 回答
33

设置选项“LIBXML_NOWARNING”和“LIBXML_NOERROR”也可以正常工作:

$dom->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);
于 2018-08-03T06:50:30.513 回答
14

您可以安装一个临时错误处理程序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());
}
于 2009-07-19T00:39:39.757 回答