How to put an error check for simplexml_load_file?

2019-02-11 03:10发布

问题:

I'm using Tumbrl API to load a few posts onto my homepage. I have the following call:

$xml = simplexml_load_file($request_url);

Occasionally it loads fine but other times I get this output instead:

Warning: simplexml_load_file(http://mysite.tumblr.com/api/read?type=post&start=0&num=10&type=photo) [function.simplexml-load-file]: failed to open stream: HTTP request failed! HTTP/1.1 503 Service Temporarily Unavailable in mysite.com/html/index.php on line 624

Warning: simplexml_load_file() [function.simplexml-load-file]: I/O warning : failed to load external entity "http://mysite.tumblr.com/api/read?type=post&start=0&num=10&type=photo" in mysite.com/html/index.php on line 624

What kind of error check should I implement to avoid showing the warning on the page?

回答1:

The way to check for failure of this function is to check for a false return value.

simplexml_load_file also fires an old-style PHP warning when it fails. If you have warnings turned on but you want to suppress the warning for whatever reason, you could use @:

So, you can use

$element = @simplexml_load_file($file);
if ($element === false) {
  // error!
}

Note that the warning can be an indicator of a possible problem. If you are reading a file but you are not sure if that file exists, have you been careful to avoid a security problem? For example, are users able to read any file on your system?

Update March 2014

As a caveat, I should add that using the "@" operator to suppress an error is a bad idea in general. If there is an alternative, you should use it. If there isn't an alternative, you should try to restrict the part covered by "@" to the smallest possible part.

The reason for this is that "@" overrides any error handling settings you have set globally (in the same way as setting error_reporting() in your code). So if you've set PHP to log errors instead of display them, for example, this error won't even be logged. It's also easy to accidentally suppress more errors than you intend with "@" including errors you'd want to know about. For example, using @myfunction($something) will suppress errors that happen anywhere in that function, or in functions that function calls in turn. So this is just something to keep in mind about that operator.

In this case, because you are checking remote files over HTTP, the usual alternative to using "@" is not ideal. Eg for local files you may use the following to avoid "@":

if (file_exists($file)) {
  $element = simplexml_load_file($file);
}
else {
  // error!
}

But in your case since it is a call to a remote file over HTTP, the above would result in two requests and if the first request succeeds but the second one fails, you'd get an error. In your case an "@" operator specifically limited to your simplexml_load_file() is probably the best.