Отключить предупреждения при загрузке неверно сформированного HTML с помощью DomDocument (PHP)
Мне нужно разбирать некоторые 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)
может подавлять предупреждения, но как я могу зафиксировать эти предупреждения программно?
Ответы
Ответ 1
Вы можете установить временный обработчик ошибок с помощью 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());
}
Ответ 2
Вызов
libxml_use_internal_errors(true);
до обработки с помощью $xmlDoc->loadHTML()
Это говорит libxml2 не отправлять ошибки и предупреждения через PHP. Затем, чтобы проверить ошибки и обработать их самостоятельно, вы можете обратиться к libxml_get_last_error() и/или libxml_get_errors(), когда вы будете готовы.
Ответ 3
Чтобы скрыть предупреждения, вы должны дать специальные инструкции libxml
, которые используются внутри для синтаксического анализа:
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
libxml_use_internal_errors(true)
указывает, что вы будете обрабатывать ошибки и предупреждения самостоятельно, и вы не хотите, чтобы они испортили вывод вашего script.
Это не то же самое, что и оператор @
. Предупреждения собираются за кулисами, после чего вы можете получить их с помощью 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);