Работа с ошибками 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 & without throwing warnings:
$str = preg_replace('/&(?!;{6})/', '&', $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' : '&'.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
189k51 gold badges425 silver badges823 bronze badges
asked Aug 20, 2009 at 16:13
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
189k51 gold badges425 silver badges823 bronze badges
answered Jan 3, 2011 at 8:59
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
answered Dec 14, 2011 at 9:01
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ņš 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
![]()
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.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 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.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
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
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
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
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
![]()
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.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
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
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
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
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
![]()
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 по умолчанию.