views:

305

answers:

3

I am querying an API using SimpleXML which will occasionally fail for reasons unknown. I would like to have the script retry up to 5 times. How can I do this? I assume it has something to do with wrapping the object in a try/catch, but I'm not very experienced with this -- have tried to read the manual on exception handling but am still at a loss.

Thanks for any help :)

// set up xml handler
$xmlstr = file_get_contents($request);
$xml = new SimpleXMLElement($xmlstr);

Here is the error message I am receiving:

[function.file-get-contents]: failed to open stream: HTTP request failed!

A: 

One example way of using try ... catch you describe. This isn't really dealing with the error but it retries 5 times. I'd recommend trying to diagnose the issue causing intermittent failures.

class MyClass {

    protected $xml;

    public function readAPI() {

        ...
        $loaded = false;
        $fetch = 5;

        while (!$loaded && $fetch) {
            $loaded = $this->_loadXML($request);
            $fetch--;
        }

    }

    protected function _loadXML($request) {

        $result = true;

        try {
            $xmlStr = file_get_contents($request);
            $this->xml = new SimpleXMLElement($xmlStr);
        } catch (Exception $e) {
            $result = false;
        }

        return $result;
    }
}

You might want to throw the Exception again and catch it higher up the calling code.

Greg K
As far as I know `try .. catch` will only catch `Exception`s, not regular errors. So this `try .. catch` will not work as expected with `file_get_contents`.
fireeyedboy
OK, I assumed he was having a problem with Simple XML throwing errors.
Greg K
A: 

A try .. catch block will not catch regular errors, but only Exceptions, unless you set up set_error_handler to have errors be translated to ErrorExceptions. Seeing that the problem lies in the file_get_contents something like this might be a better option (untested):

$maxTries = 5;
do
{
  // supress the error with @ (or log it) and probe the output in while condition
  $content = @file_get_content( $someUrl );
}
while( false === $content && --$maxTries );

if( false !== $content )
{
   try
   {
      // SimpleXMLElement *will* throw an exception in case of malformed xml
      $xml = new SimpleXMLElement( $content );
   }
   catch( Exception $exception )
   {
      /* handle exception */
   }
}
else
{
    /* handle file_get_contents failure */
}

However, since you are trying to read from a http url, I presume the failure has something to do with the ini setting on whether url requests are allowed for opening files. See the docs on allow_url_fopen. Is something/someone altering this setting now and then perhaps?

Scrap that... it's highly unlikely, since it can not be set at runtime (PHP > 4.3.4 that is).

fireeyedboy
thank you, this is the kind of thing I am looking for. Basically am making a web service call 10,000 times that fails a small but non-zero amount of times but seems to work ok with a refresh.
exceptionhandlingnoob
A: 

try using curl to get the content you want to parse... file_get_contents can fail without much explanation about it. also try to dont use @ (this hide you errors that can make die the application) or you can just use to code in a wrong way just because you can hide the warnings

Gabriel Sosa