Stopping a simplexml_load_file() function after a few seconds

Hello everyone. I would really appreciate your help PHP masters as I was not able to find the solution by my self. The problem is as follows:

I’m using the simple_xml_load_file function to fetch some xml from Youtube in order to embed a video with the oembed technique. The code is:


$xml = simplexml_load_file("http://www.youtube.com/oembed?url=".$post['embed']."&format=xml")

Nothing at all wrong with that. When a connection is made to Youtube everything is great. However when it cannot make a connection it will spend a minute trying to do so without loading the rest of the script. That wouldn’t bother me a lot but for the fact that I’m in China and Youtube is banned here. So every time I’m testing a page with a Youtube embed I rather not because the script will hang up for a minute until it decides that it cannot get the requested XML . So my question is: How can I abort the code above after a given amount of seconds, is it a php.ini setting or is there a way I can do this with php code?

Your help would be really appreciated,

thanks :slight_smile:

There are a fair few ways to do this, here’s one. :slight_smile:


function simplexml_load_file_from_url($url, $timeout = 5){
  
  $context = array('http' => array('timeout' => (int)$timeout));
  
  $data = file_get_contents($url, false, $context);
  
  if(!$data){
    trigger_error('Cannot load data from url: ' . $url, E_USER_NOTICE);
    return false;
  }
  
  return simplexml_load_string($data);
}

CURL should be used because file_get_contents() only fails once the max execution time of php has been reached. Using CURL time before abort can be controlled. So you would first load the contents into a string using cURL than into a smplexml object when the request was successful otherwise handle the exception gracefully. Its never a good idea to use file_get_contents() to fetch external content from another site due to the execution time only be limited to the that of what is set for the php max execution time.

Does this apply even when a context has been applied stating otherwise Oddz?

Thank you for both answers , I will look into them :slight_smile: But of course if I can avoid using a library I will

No. I’ve no idea what oddz is talking about. There is a configuration option relating to this topic which is default_socket_timeout (default: 60 seconds). This setting affects file_get_contents() unless a stream context is used with a timeout.

Now, some more thoughts. First is that Anthony’s function should be using the [url=http://php.net/stream_context_create]stream_context_create() function to actually create a context.

Next, as mentioned above, you could temporarily set the default_socket_timeout INI option to something less than the 60 seconds currently being used. Or you could use a stream context with file_get_contents() as Anthony (nearly) showed. Or you could use a stream context with simplexml_load_file() via the libxml_set_streams_context() function.

Gah, sorry Salathe; a mishap on my part. :slight_smile:

Thanks Salathe and Anthony, very useful info!
As for performance are there any differences from using file_get_contents() or simplexml_load_file()? I noticed a slight delay on page load sometimes when using simplexml_load_file() although it might not have anything to do with how the function works.

Thanks again wise people!