почему эта функция обработки ошибок приводит к зависанию domdocument ()? - PullRequest
0 голосов
/ 20 августа 2011

Я включил эту простую функцию обработки ошибок для форматирования ошибок:

<code>date_default_timezone_set('America/New_York');

// Create the error handler.
function my_error_handler ($e_number, $e_message, $e_file, $e_line, $e_vars) {

    // Build the error message.
    $message = "An error occurred in script '$e_file' on line $e_line: \n<br />$e_message\n<br />";

    // Add the date and time.
    $message .= "Date/Time: " . date('n-j-Y H:i:s') . "\n<br />";

    // Append $e_vars to the $message.
    $message .= "<pre>" . print_r ($e_vars, 1) . "
\ n"; echo ''.$ сообщение.««;} // Конец определения my_error_handler ().// Использовать мой обработчик ошибок.set_error_handler ('my_error_handler');

Когда я включаю его в скрипт со следующим

$dom = new DOMDocument();
$dom->loadHTML($output);
$xpath = new DOMXPath($dom);

и анализирую веб-страницу (в данном случае, http://www.ssense.com/women/designers/all/all/page_1,, на которую у меня есть разрешениедля разбора) я получаю ошибки типа

AN ERROR OCCURRED IN SCRIPT '/HSPHERE/LOCAL/HOME/SITE.COM/SCRIPT.PHP' ON LINE 59: 
DOMDOCUMENT::LOADHTML(): HTMLPARSEENTITYREF: NO NAME IN ENTITY, LINE: 57

и

AN ERROR OCCURRED IN SCRIPT '/HSPHERE/LOCAL/HOME/SITE.COM/SCRIPT.PHP' ON LINE 59: 
DOMDOCUMENT::LOADHTML(): TAG NAV INVALID IN ENTITY, LINE: 58

Есть много ошибок, и страница никогда не завершает загрузку.Однако, если я не включу этот обработчик ошибок, строка

$dom->loadHTML($output);

не выдаст никаких ошибок, и я получу ожидаемые результаты через несколько секунд.Я предполагаю, что обработчик ошибок перехватывает предупреждения, связанные с loadHTML (), о которых не сообщается иначе.(Даже если я использую

@$dom->loadHTML($output);

, он все равно сообщает об ошибках.) Как я могу изменить обработчик ошибок, чтобы он соответствовал вызовам loadHTML (), или иным образом решить эту проблему?

Ответы [ 2 ]

3 голосов
/ 20 августа 2011

Загружаемая веб-страница содержит много ошибок.Например, & вместо сущности &amp; в HTML.

PHP DOM использует libxml, поэтому для отключения всех ошибок вставьте строку:

libxml_use_internal_errors(true);

.получить список ошибок синтаксического анализа с помощью libxml_get_errors () .

2 голосов
/ 20 августа 2011

Это не пользовательский обработчик ошибок, который вызывает ошибку.

Я запустил следующий код без специального обработчика ошибок:

$output = file_get_contents("http://www.ssense.com/women/designers/all/all/page_1");
$dom = new DOMDocument();
$dom->loadHTML($output);
$xpath = new DOMXPath($dom);

Когда я его запустил, я получил тоннупредупреждающих сообщений, похожих на те, что есть в вашем обработчике ошибок.

Я думаю, что проблема, которую вы видите, заключается в том, что ваш обработчик ошибок сообщает об ошибках, которые PHP не сообщает по умолчанию.

По умолчанию уровень отчетов об ошибках определяется вашими настройками php.ini, но может быть изменен с помощью функции error_reporting().Когда вы устанавливаете свой собственный обработчик ошибок, вы должны сами определить, с каким уровнем отчетности вы хотите иметь дело.Ваш обработчик ошибок будет вызываться при каждой ошибке и уведомлении, и поэтому вы будете выводить сообщения об ошибках для всего , если только вы явно не сверяете генерируемую ошибку с текущим уровнем error_reporting().

Помните, что использование оператора подавления ошибок @ является просто сокращением для установки error_reporting(0) для этой строки.Например, эта строка:

@$dom->loadHTML($output);

- это просто сокращение для следующего:

$errorLevel = error_reporting(0);
$dom->loadHTML($output);
error_reporting($errorLevel);

Поскольку обычное сообщение об ошибках PHP полностью игнорируется при использовании пользовательского обработчика, при использовании @Оператор не имеет смысла, так как текущий уровень error_reporting() полностью игнорируется.Вам нужно было бы написать собственный код в свой обработчик ошибок, чтобы проверить текущий уровень error_reporting() и обработать его соответствующим образом, например:

function my_error_handler() {
  if (error_reporting() == 0) {
    return; // do nothing when error_reporting is disabled.
  }

  // normal error handling here
}

Я предполагаю, что, когда не используется специальный обработчик ошибок, PHPпросто по умолчанию установлен на уровень error_reporting(), который ниже производимых ошибок.

Если вы добавите error_reporting(E_ALL | E_STRICT); в начало вашего кода, вы увидите те же ошибки, даже если у вас нетВаш пользовательский обработчик ошибок включен.

...