Reputation: 1395
I am connecting to an unreliable API via file_get_contents. Since it's unreliable, I decided to put the api call into a while loop thusly:
$resultJSON = FALSE;
while(!$resultJSON) {
$resultJSON = file_get_contents($apiURL);
set_time_limit(10);
}
Putting it another way: Say the API fails twice before succeeding on the 3rd try. Have I sent 3 requests, or have I sent however many hundreds of requests as will fit into that 3 second window?
Upvotes: 5
Views: 6165
Reputation: 8743
Yes, it is a blocking function. You should also check to see if the value is specifically "false". (Note that === is used, not ==.) Lastly, you want to sleep for 10 seconds. set_time_limit() is used to set the max execution time before it is automatically killed.
set_time_limit(300); //Run for up to 5 minutes.
$resultJSON = false;
while($resultJSON === false)
{
$resultJSON = file_get_contents($apiURL);
sleep(10);
}
Upvotes: 2
Reputation: 32272
I am not aware of any function in PHP that does not "block". As an alternative, and if your server permits such things, you can:
pcntl_fork()
and do other stuff in your script while waiting for the API call to go through.exec()
to call another script in the background [using &
] to do the API call for you if pcntl_fork()
is unavailable.However, if you literally cannot do anything else in your script without a successful call to that API then it doesn't really matter if the call 'blocks' or not. What you should really be concerned about is spending so much time waiting for this API that you exceed the configured max_execution_time
and your script is aborted in the middle without being properly completed.
$max_calls = 5;
for( $i=1; $i<=$max_calls; $i++ ) {
$resultJSON = file_get_contents($apiURL);
if( $resultJSON !== false ) {
break;
} else if( $i = $max_calls ) {
throw new Exception("Could not reach API within $max_calls requests.");
}
usleep(250000); //wait 250ms between attempts
}
It's worth noting that file_get_contents()
has a default timeout of 60 seconds so you're really in danger of the script being killed. Give serious consideration to using cURL instead since you can set much more reasonable timeout values.
Upvotes: 1
Reputation: 461
Expanding on @Sammitch suggestion to use cURL instead of file_get_contents()
:
<?php
$apiURL = 'http://stackoverflow.com/';
$curlh = curl_init($apiURL);
// Use === not ==
// if ($curlh === FALSE) handle error;
curl_setopt($curlh, CURLOPT_FOLLOWLOCATION, TRUE); // maybe, up to you
curl_setopt($curlh, CURLOPT_HEADER, FALSE); // or TRUE, according to your needs
curl_setopt($curlh, CURLOPT_RETURNTRANSFER, TRUE);
// set your timeout in seconds here
curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curlh, CURLOPT_TIMEOUT, 30);
$resultJSON = curl_exec($curlh);
curl_close($curlh);
// if ($resultJSON === FALSE) handle error;
echo "$resultJSON\n"; // Now process $resultJSON
?>
There are a lot more curl_setopt
options. You should check them out.
Of course, this assumes you have cURL available.
Upvotes: 1
Reputation:
file_get_contents()
, like basically all functions in PHP, is a blocking call.
Upvotes: 9