Rápli András Rápli András - 3 months ago 24
PHP Question

Catch SimpleXML Exception only?

SimpleXML throws a regular Exception, how could I differentiate this from other exceptions if the class is the same?

Answer

The problem you have is very local and can be easily handled.

Instead of using

$xml = new SimpleXMLElement($buffer);

(the exception-case is that $buffer = '')

You can make use of a function that tells you whether or not loading of the buffer did work w/o throwing an exception:

$xml = simplexml_load_string($buffer);

In case of an error, $xml will be false. So you don't have the exception problem in the first place.

Additionally I suggest you make the code more stable as well if you're interested in more detailed error handling, like checking preconditions and postconditions for the function call:

if (!is_string($buffer) || !strlen($buffer)) {
    throw new UnexpectedValueException("String with length required");
}

$xml = simplexml_load_string($buffer);
if (!$xml) {
    throw new UnexpectedValueException('String could not be parsed as XML');
}

This also shows how you can throw the exceptions you like. However as you're only concerned about a single line of code you can just catch any exception and deal with the single error-case you have there:

try {
    $xml = new SimpleXMLElement($buffer);
} catch (Exception $e) {
    $xml = false;
}

But then, using simplexml_load_string might be more handy.

Next to that, you can also enable internal error reporting of libxml and find out more about the actual problems when creating the object:

$saved  = libxml_use_internal_errors(true);
$xml    = simplexml_load_string($buffer);
$errors = libxml_get_errors();
libxml_use_internal_errors($saved);

if (!$xml) {
    var_dump($errors); // create and throw a specific exception here based on errors.
}

However, an empty string won't create any error, better take care if it with a precondition check.

Additionally:

  • Make the cron-job save to a different filename while donwloading, replacing the file only when ready.
  • Open the file read-only.