29

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:[email protected]/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://[email protected]/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?

2
  • 1
    Consider changing the selected answer? The question asks "How can I handle these errors?" the selected answer merely tells you how to avoid having to. Commented Apr 26, 2017 at 3:25
  • 1
    @TimOgilvy done, thanks. Commented Jul 21, 2018 at 12:45

6 Answers 6

51

You can disable PHP warnings and get error messages in the form of array instead:

$use_errors = libxml_use_internal_errors(true);
$xml = simplexml_load_file($url);
if (false === $xml) {
  // here you can use libxml_get_errors() to get error messages
  // and either format them nicely for the user or log for the admin
}
libxml_clear_errors();
libxml_use_internal_errors($use_errors);

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

Sign up to request clarification or add additional context in comments.

3 Comments

Only one that answers the question. Use it with libxml_get_errors() or libxml_get_last_error() to get the error message(s).
However, this CANNOT get all warning messages dumped by simplexml_load_file.
I tried this but got a warning message, so I simply did $xml = @simplexml_load_file($url); and no warnings and handles error as expected
29

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 XML\n";
    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

1 Comment

However, this CANNOT get all warning messages dumped by simplexml_load_string.
10

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);

2 Comments

Didn't work for me, still generated an E_WARNING in PHP 5.4.x
This answer is a simple solution that works, saved me headache! Note to those that may have errors: if you have more than one LIBXML_XXXX, be sure to seperate by pipe like LIBXML_NOCDATA | LIBXML_COMPACT | LIBXML_NOWARNING
7

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.
}

Comments

4

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

Comments

-1

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!';
}

6 Comments

Not the shut-up not the shut up, please !
so something like this? function GetTwitterAvatar($username){ if(@simplexml_load_file("twitter.com/users/".$username.".xml")){ $xml = simplexml_load_file("twitter.com/users/".$username.".xml"); $imgurl = $xml->profile_image_url; return $imgurl; } else { return 'error'; } }
You can do it without calling simplexml_load_file twice: $xml = @simplexml_load_file("..."); if ($xml) { ... } else { return 'Error'; }
mere-teresa, but he needs to suppress the warning here... Of course, you can also use the display_errors setting or convert errors to exceptions and then use try/catch, but this is much simpler...
@IgnasR you can do it even simpler: if (!$xml = simplexml_load_file($file)) { echo 'Error!'; return false; } else { //your code }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.