Меню

Обработка ошибок xml php

Работа с ошибками XML при загрузке документов является очень простой задачей.
Использование функциональности libxml
позволяет подавить все XML-ошибки при загрузке документа и затем обработать их.

Объект libXMLError, возвращаемый
libxml_get_errors(), содержит несколько свойств,
в том числе сообщение,
номер строки и
колонку (позицию) этой
ошибки.

Пример #1 Загрузка синтаксически неправильной XML-строки


<?php
libxml_use_internal_errors
(true);
$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (!
$sxe) {
echo
"Ошибка загрузки XMLn";
foreach(
libxml_get_errors() as $error) {
echo
"t", $error->message;
}
}
?>

Результат выполнения данного примера:

Ошибка загрузки XML
    Blank needed here
    parsing XML declaration: '?>' expected
    Opening and ending tag mismatch: xml line 1 and broken
    Premature end of data in tag broken line 1

openbip at gmail dot com

12 years ago


Note that "if (! $sxe) {" may give you a false-negative if the XML document was empty (e.g. "<root />").  In that case, $sxe will be:

object(SimpleXMLElement)#1 (0) {
}

which will evaluate to false, even though nothing technically went wrong.

Consider instead: "if ($sxe === false) {"


1337 at netapp dot com

7 years ago

tuxedobob

8 years ago


Now that the /e modifier is considered deprecated in preg_replace, you can use a negative lookahead to replace unescaped ampersands with &amp; without throwing warnings:

$str = preg_replace('/&(?!;{6})/', '&amp;', $str);

You probably should have been doing this before /e was deprecated, actually.


Jacob Tabak

12 years ago


If you are trying to load an XML string with some escaped and some unescaped ampersands, you can pre-parse the string to ecsape the unescaped ampersands without modifying the already escaped ones:
<?php
$s
= preg_replace('/&[^; ]{0,6}.?/e', "((substr('\0',-1) == ';') ? '\0' : '&amp;'.substr('\0',1))", $s);
?>

I am using the following code:

function GetTwitterAvatar($username){
$xml = simplexml_load_file("http://twitter.com/users/".$username.".xml");
$imgurl = $xml->profile_image_url;
return $imgurl;
}

function GetTwitterAPILimit($username, $password){
$xml = simplexml_load_file("http://$username:$password@twitter.com/account/rate_limit_status.xml");
$left = $xml->{"remaining-hits"};
$total = $xml->{"hourly-limit"};
return $left."/".$total;
}

and getting these errors when the stream cannot connect:

Warning: simplexml_load_file(http://twitter.com/users/****.xml) [function.simplexml-load-file]: failed to open stream: HTTP request failed! HTTP/1.0 503 Service Unavailable

Warning: simplexml_load_file() [function.simplexml-load-file]: I/O warning : failed to load external entity "http://twitter.com/users/****.xml" 

Warning: simplexml_load_file(http://...@twitter.com/account/rate_limit_status.xml) [function.simplexml-load-file]: failed to open stream: HTTP request failed! HTTP/1.0 503 Service Unavailable

Warning: simplexml_load_file() [function.simplexml-load-file]: I/O warning : failed to load external entity "http://***:***@twitter.com/account/rate_limit_status.xml"

How can I handle these errors so I can display a user friendly message instead of what is shown above?

hakre's user avatar

hakre

189k51 gold badges425 silver badges823 bronze badges

asked Aug 20, 2009 at 16:13

mrpatg's user avatar

2

I thinks this is a better way

$use_errors = libxml_use_internal_errors(true);
$xml = simplexml_load_file($url);
if (false === $xml) {
  // throw new Exception("Cannot load xml source.n");
}
libxml_clear_errors();
libxml_use_internal_errors($use_errors);

more info: http://php.net/manual/en/function.libxml-use-internal-errors.php

hakre's user avatar

hakre

189k51 gold badges425 silver badges823 bronze badges

answered Jan 3, 2011 at 8:59

Alex's user avatar

AlexAlex

1,5121 gold badge15 silver badges17 bronze badges

3

I’ve found a nice example in the php documentation.

So the code is:

libxml_use_internal_errors(true);
$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (false === $sxe) {
    echo "Failed loading XMLn";
    foreach(libxml_get_errors() as $error) {
        echo "t", $error->message;
    }
}

And the output, as we/I expected:

Failed loading XML

Blank needed here
parsing XML declaration: '?>' expected
Opening and ending tag mismatch: xml line 1 and broken
Premature end of data in tag broken line 1

Community's user avatar

answered Dec 14, 2011 at 9:01

Briganti's user avatar

BrigantiBriganti

8497 silver badges11 bronze badges

1

If you look at the manual, there is an options parameter:

SimpleXMLElement simplexml_load_file ( string $filename [, string $class_name = "SimpleXMLElement" [, int $options = 0 [, string $ns = "" [, bool $is_prefix = false ]]]] )

Options list is available: http://www.php.net/manual/en/libxml.constants.php

This is the correct way to suppress warnings parsing warnings:

$xml = simplexml_load_file('file.xml', 'SimpleXMLElement', LIBXML_NOWARNING);

answered Apr 17, 2013 at 5:17

Mārtiņš Briedis's user avatar

Mārtiņš BriedisMārtiņš Briedis

17.1k5 gold badges54 silver badges74 bronze badges

2

This is an old question, but is still relevant today.

The correct way to handle exceptions when using the oop SimpleXMLElment is like so.

libxml_use_internal_errors(TRUE); // this turns off spitting errors on your screen
try {
  $xml = new SimpleXMLElement($xmlStringOfData);
} catch (Exception $e) {
  // Do something with the exception, or ignore it.
}

answered Nov 23, 2015 at 15:07

Halfstop's user avatar

HalfstopHalfstop

1,70017 silver badges34 bronze badges

My little code:

try {
    libxml_use_internal_errors(TRUE);
    $xml = new SimpleXMLElement($xmlString);
    echo '<pre>'.htmlspecialchars($xml->asXML()).'</pre>';
} catch (Exception $e) {
    echo 'Caught exception: ' . $e->getMessage() . chr(10);
    echo 'Failed loading XML: ' . chr(10);
    foreach(libxml_get_errors() as $error) {
        echo '- ' . $error->message;
    }
}

Result example:

Caught exception: String could not be parsed as XML
Failed loading XML: 
- Opening and ending tag mismatch: Body line 3 and Bod-y

answered Feb 28, 2017 at 8:31

Robert G.'s user avatar

Robert G.Robert G.

2772 silver badges8 bronze badges

The documentation says that in the case of an error, simplexml_load_file returns FALSE. So, you can use the «shut-up» operator (@) in combination with a conditional statement:

if (@simplexml_load_file($file))
{
    // continue
}
else 
{
    echo 'Error!';
}

answered Aug 20, 2009 at 16:16

Ignas R's user avatar

Ignas RIgnas R

3,2942 gold badges22 silver badges27 bronze badges

6

Работа с ошибками XML при загрузке документов является очень простой задачей.
Использование функциональности libxml
позволяет подавить все XML ошибки при загрузке документа и затем обработать их.

Объект libXMLError, возвращаемый
libxml_get_errors(), содержит несколько свойств,
в том числе сообщение,
номер строки и
колонку (позицию) этой
ошибки.

Пример #1 Загрузка синтаксически неправильной XML строки


<?php
libxml_use_internal_errors
(true);
$sxe simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (
$sxe === false) {
    echo 
"Ошибка загрузки XMLn";
    foreach(
libxml_get_errors() as $error) {
        echo 
"t"$error->message;
    }
}
?>

Результат выполнения данного примера:

Ошибка загрузки XML
    Blank needed here
    parsing XML declaration: '?>' expected
    Opening and ending tag mismatch: xml line 1 and broken
    Premature end of data in tag broken line 1

Вернуться к: Примеры

In my application I am loading xml from url in order to parse it.
But sometimes this url may not be valid. In this case I need to handle errors.
I have the following code:

$xdoc = new DOMDocument();
try{
  $xdoc->load($url); // This line causes Warning: DOMDocument::load(...)
                     // [domdocument.load]: failed to open stream: 
                     // HTTP request failed! HTTP/1.1 404 Not Found in ...
} catch (Exception $e) {
  $xdoc = null;
}

if($xdoc == null){
  // Handle
} else {
  // Proceed
}

I know I probably doing it wrong, but what’s a correct way to handle this kind of exceptions? I don’t want to see error messages on my page.

The manual for DOMDocument::load() says:

If an empty string is passed as the
filename or an empty file is named, a
warning will be generated. This
warning is not generated by libxml and
cannot be handled using libxml’s error
handling functions.

But there is no information on how to handle it.

Thanks.

asked Nov 18, 2009 at 21:03

Maksim Vi.'s user avatar

Maksim Vi.Maksim Vi.

9,00712 gold badges58 silver badges85 bronze badges

From what I can gather from the documentation, handling warnings issued by this method is tricky because they are not generated by the libxml extension and thus cannot be handled by libxml_get_last_error(). You could either use the error suppression operator and check the return value for false

if (@$xdoc->load($url) === false)
    // ...handle it

…or register an error handler which throws an exception on error:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

and then catch it.

answered Nov 18, 2009 at 21:17

Øystein Riiser Gundersen's user avatar

2

set_error_handler(function($number, $error){
    if (preg_match('/^DOMDocument::loadXML(): (.+)$/', $error, $m) === 1) {
        throw new Exception($m[1]);
    }
});

$xml = new DOMDocument();
$xml->loadXML($xmlData);

restore_error_handler();

That works for me in PHP 5.3. But if you’re not using loadXML, you might need to do some modifications.

answered Mar 24, 2011 at 9:59

Znarkus's user avatar

ZnarkusZnarkus

23k22 gold badges78 silver badges108 bronze badges

2

To disable throwing errors:

$internal_errors = libxml_use_internal_errors(true);

$dom = new DOMDocument();
// etc...

libxml_use_internal_errors($internal_errors);

answered Sep 19, 2011 at 1:36

Petah's user avatar

PetahPetah

44.9k28 gold badges156 silver badges212 bronze badges

2

From php.net

If an empty string is passed as the
filename or an empty file is named, a
warning will be generated. This
warning is not generated by libxml and
cannot be handled using libxml’s error
handling functions.

In your production environment you shouldn’t have errors displayed to the user. They don’t need to see them so taking this into account you can use…

$xdoc = new DOMDocument();
if ( $xdoc->load($url) ) {
    // valid
}
else {
    // invalid
}

answered Nov 18, 2009 at 21:18

Galen's user avatar

GalenGalen

29.9k9 gold badges71 silver badges89 bronze badges

1

For me , following did the trick

$feed = new DOMDocument();  
$res= @$feed->load('http://www.astrology.com/horoscopes/daily-extended.rss');
if($res==1){
           //do sth
          }

answered Jun 30, 2014 at 16:05

sumit's user avatar

sumitsumit

14.6k11 gold badges63 silver badges108 bronze badges

In my application I am loading xml from url in order to parse it.
But sometimes this url may not be valid. In this case I need to handle errors.
I have the following code:

$xdoc = new DOMDocument();
try{
  $xdoc->load($url); // This line causes Warning: DOMDocument::load(...)
                     // [domdocument.load]: failed to open stream: 
                     // HTTP request failed! HTTP/1.1 404 Not Found in ...
} catch (Exception $e) {
  $xdoc = null;
}

if($xdoc == null){
  // Handle
} else {
  // Proceed
}

I know I probably doing it wrong, but what’s a correct way to handle this kind of exceptions? I don’t want to see error messages on my page.

The manual for DOMDocument::load() says:

If an empty string is passed as the
filename or an empty file is named, a
warning will be generated. This
warning is not generated by libxml and
cannot be handled using libxml’s error
handling functions.

But there is no information on how to handle it.

Thanks.

asked Nov 18, 2009 at 21:03

Maksim Vi.'s user avatar

Maksim Vi.Maksim Vi.

9,00712 gold badges58 silver badges85 bronze badges

From what I can gather from the documentation, handling warnings issued by this method is tricky because they are not generated by the libxml extension and thus cannot be handled by libxml_get_last_error(). You could either use the error suppression operator and check the return value for false

if (@$xdoc->load($url) === false)
    // ...handle it

…or register an error handler which throws an exception on error:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

and then catch it.

answered Nov 18, 2009 at 21:17

Øystein Riiser Gundersen's user avatar

2

set_error_handler(function($number, $error){
    if (preg_match('/^DOMDocument::loadXML(): (.+)$/', $error, $m) === 1) {
        throw new Exception($m[1]);
    }
});

$xml = new DOMDocument();
$xml->loadXML($xmlData);

restore_error_handler();

That works for me in PHP 5.3. But if you’re not using loadXML, you might need to do some modifications.

answered Mar 24, 2011 at 9:59

Znarkus's user avatar

ZnarkusZnarkus

23k22 gold badges78 silver badges108 bronze badges

2

To disable throwing errors:

$internal_errors = libxml_use_internal_errors(true);

$dom = new DOMDocument();
// etc...

libxml_use_internal_errors($internal_errors);

answered Sep 19, 2011 at 1:36

Petah's user avatar

PetahPetah

44.9k28 gold badges156 silver badges212 bronze badges

2

From php.net

If an empty string is passed as the
filename or an empty file is named, a
warning will be generated. This
warning is not generated by libxml and
cannot be handled using libxml’s error
handling functions.

In your production environment you shouldn’t have errors displayed to the user. They don’t need to see them so taking this into account you can use…

$xdoc = new DOMDocument();
if ( $xdoc->load($url) ) {
    // valid
}
else {
    // invalid
}

answered Nov 18, 2009 at 21:18

Galen's user avatar

GalenGalen

29.9k9 gold badges71 silver badges89 bronze badges

1

For me , following did the trick

$feed = new DOMDocument();  
$res= @$feed->load('http://www.astrology.com/horoscopes/daily-extended.rss');
if($res==1){
           //do sth
          }

answered Jun 30, 2014 at 16:05

sumit's user avatar

sumitsumit

14.6k11 gold badges63 silver badges108 bronze badges

PHP5 Обработка ошибок



Обработка ошибок по умолчанию в PHP очень проста. Сообщение об ошибке с именем файла, строка число и сообщение, описывающее ошибку, отправляется в браузер.


При создании скриптов и веб-приложений, обработка ошибок, является важной
частью. Если коду не хватает кода проверки ошибок, программа может выглядеть
непрофессионально и Вы можете быть открыты для рисков безопасности.

Учебник содержит несколько из наиболее распространенных методов проверки ошибок в PHP.

Вы узнаете различные методы обработки ошибок:

  • Простое заявление это()
  • Пользовательские ошибки и триггеры ошибок
  • Отчеты об ошибках

PHP Основная обработка ошибок

В первом примере показан простой скрипт, открывающий текстовый файл: использование функции это()

Пример

<?php
$file=fopen(«welcome.txt»,»r»);
?>

Если файл не существует, Вы можете получить ошибку, как эта:

Внимание: fopen(welcome.txt) [function.fopen]: не удалось открыть поток:
Нет такого файла или каталога в C:webfoldertest.php на линии 2

Чтобы запретить пользователю получать сообщение об ошибке, подобное приведенному примеру выше, мы проверяем
файл, существует ли он до того, как мы попытаемся получить к нему доступ:

Пример

<?php
if(!file_exists(«welcome.txt»)) {
  die(«Файл не найден»);
}
else {
  $file=fopen(«welcome.txt»,»r»);
}
?>

Теперь, если файл не существует вы получите ошибку, как эта:

Файл не найден

Приведенный ниже код более эффективен, чем предыдущий код, поскольку он использует простой механизм обработки ошибок для остановки сценария после ошибки.

Тем не менее, остановить просто сценарий не всегда правильный путь. Рассмотрим альтернативные функции PHP для обработки ошибок.


PHP Создание пользовательского обработчика ошибок

Создать пользовательский обработчик ошибок довольно просто. Создаем специальную функцию, которая может быть вызвана при возникновении ошибки в PHP.

Эта функция должна быть способна обрабатывать, как минимум два параметра (уровень ошибки и сообщение об ошибке),
но можно принимать до пяти параметров (дополнительно: файл, номер строки и контекст ошибки):

Синтаксис

error_function(error_level,error_message,
error_file,error_line,error_context)

Параметр Описание
error_level Необходимо. Указывает уровень отчета об ошибках для пользовательской ошибки.
Должно быть числовое значение. См. таблицу ниже для возможных уровней отчета об ошибках
error_message Необходимо. Указывает сообщение об ошибке определяемая пользователем
error_file Необязательно. Задает имя файла, в котором произошла ошибка
error_line Необязательно. Указывает номер строки, в которой произошла ошибка
error_context Необязательно. Задает массив, содержащий все переменные и их значения, используемые при возникновении ошибки

PHP Уровни отчетов об ошибках

Эти уровни отчетов об ошибках, являются различными типами ошибок, для которых может использоваться определяемый пользователем обработчик ошибок:

Значение Констант Описание
2 E_WARNING Неустранимые ошибки выполнения. Выполнение скрипта не останавливается
8 E_NOTICE Уведомления среды выполнения. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария, как обычно
256 E_USER_ERROR Неустранимая ошибка пользователя. Это похоже на набор E_ERROR установленный программистом с помощью функции PHP trigger_error()
512 E_USER_WARNING Неустранимое пользовательское предупреждение. Это похоже на набор E_WARNING установленный программистом с помощью функции PHP trigger_error()
1024 E_USER_NOTICE Автоматическое уведомление пользователя. Это похоже на набор E_NOTICE устанавливается программистом с помощью функции PHP trigger_error()
4096 E_RECOVERABLE_ERROR Перехватываемая неустранимая ошибка. Это похоже на набор E_ERROR но может быть перехватана пользователем, определенной обработкой (смотреть также set_error_handler())
8191 E_ALL Все ошибки и предупреждение (E_STRICT становится частью E_ALL в PHP 5.4)

Теперь давайте создадим функцию для обработки ошибок:

Пример

function customError($errno, $errstr) {
  echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
  echo «Конечный Script»;
  die();
}

Приведенный выше код, является простой функцией обработки ошибок. Когда он срабатывает, он получает код ошибки и сообщение об ошибке.
Затем выводится уровень ошибки и сообщение и завершается сценарий.

Теперь, когда Вы создали функцию обработки ошибок, Вы должны решить, когда она должно сработать.


PHP Установить обработчик ошибок

Обработчик ошибок по умолчанию для PHP является встроенным обработчиком ошибок.
Мы собираемся сделать функцию над обработчиком ошибок по умолчанию на время скрипта.

Можно изменить обработчик ошибок для применения только к некоторым ошибкам, таким образом,
сценарий может обрабатывать различные ошибки по-разному.
Однако, в этом примере мы будем использовать наш пользовательский обработчик ошибок для всех ошибок:

set_error_handler(«customError»);

Поскольку мы хотим, чтобы наша пользовательская функция обрабатывала все ошибки, set_error_handler()
требуется только один параметр, второй параметр может быть добавлен, чтобы указать уровень ошибки.

Тестирование обработчика ошибок при попытке вывести несуществующую переменную:

Пример

<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
  echo «<b>Ошибка:</b> [$errno] $errstr»;
}

//установить обработчик ошибок
set_error_handler(«customError»);

//Вызов ошибки
echo($test);
?>

Выходные данные приведенного выше кода должны быть примерно такими:

Ошибка: [8] Неопределенна переменная: test


PHP Вызвать ошибку

В скрипте, где пользователи могут вводить данные, полезно инициировать ошибки, когда происходит незаконный ввод.
В PHP это делается с помощью функции trigger_error().

В этом примере возникает ошибка, если $test переменная больше, чем 1:

Пример

<?php
$test=2;
if ($test>=1)
{
 
trigger_error(«Значение должно быть 1 или ниже»);
}
?>

Выходные данные приведенного выше кода должны быть примерно такими:

Заметьте: Значение должно быть 1 или ниже
в C:webfoldertest.php на линии 6

Ошибка может быть вызвана в любом месте сценария и путем добавления
второй параметр, Вы можете указать, какой уровень ошибки срабатывает.

Возможные типы ошибок:

  • E_USER_ERROR — Неустранимая пользовательская ошибка выполнения. Ошибки, из которых невозможно восстановить. Выполнение скрипта прекращается
  • E_USER_WARNING — Непоправимое пользовательское предупреждение во время выполнения. Выполнение скрипта не останавливается
  • E_USER_NOTICE — Невыполнение. Уведомление о времени выполнения, созданное пользователем. Сценарий нашел что-то, что могло бы быть ошибкой, но могло бы также произойти при запуске сценария

В этом примере E_USER_WARNING происходит, если переменная $test больше, чем 1. Если происходит E_USER_WARNING мы будем использовать наш пользовательский обработчик ошибок и закончить сценарий:

Пример

<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
  echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
  echo «Закончить Script»;
  die();
}

//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);

//вызов ошибки
$test=2;
if ($test>=1) {
  trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>

Выходные данные приведенного выше кода должны быть примерно такими:

Ошибка: [512] Значение должно быть 1 или ниже
Конец скрипта

Теперь, когда мы научились создавать собственные ошибки и как их вызвать,
давайте посмотрим на ошибки.


PHP Регистрация ошибок

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

Отправка сообщений об ошибках по электронной почте, может быть хорошим способом получения уведомления о конкретных ошибках.

PHP Отправка сообщение об ошибке по электронной почте

В приведенном ниже примере мы отправим электронное письмо с сообщением об ошибке и
сценарий, если возникает ошибка:

Пример

<?php
//функция обработчика ошибок
function customError($errno, $errstr) {
  echo «<b>Ошибка:</b> [$errno] $errstr<br>»;
  echo «Веб-мастер был уведомлен»;
  error_log(«Ошибка: [$errno] $errstr»,1,
  «someone@example.com»,»От: webmaster@example.com»);
}

//установить обработчик ошибок
set_error_handler(«customError»,E_USER_WARNING);

//вызов ошибки
$test=2;
if ($test>=1) {
  trigger_error(«Значение должно быть 1 или ниже»,E_USER_WARNING);
}
?>

Выходные данные приведенного выше кода должны быть примерно такими:

Ошибка: [512] Значение должно быть 1 или ниже
Веб-мастер был уведомлен

И почта, полученная из кода выше, выглядит так:

Ошибка: [512] начение должно быть 1 или ниже

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


0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Обновление пакета office 2003 kb907417 ошибка 0x80096004 как исправить
  • Обозначение ошибок на панели приборов бмв е90