Reputation: 964
Here's the Problem:
On some websites, my code that connects to Twitter is generating a fatal error that stops PHP from running for the rest of the page load. It creates a total page kill. How can I catch this error so that I can simply display zeroes or use one of the tweet counts from the most previous successful connections?
Presumably, this is because a site that has this code on it has hit the Twitter API limits. But in the rare cases where that does happen, I need it to fail gracefully so that I can just use my previously fetched tweet count.
Here's the code:
If the user has the Twitter Button active, we fetch the share count:
$social = new shareCount($url);
if( $options['twitter'] ) $tweets = $social->get_tweets();
This is where that function request gets passed inside the shareCount class:
function get_tweets() {
$json_string = file_get_contents_curl('https://urls.api.twitter.com/1/urls/count.json?url=' . $this->url);
$json = json_decode($json_string, true);
return isset($json['count'])?intval($json['count']):0;
}
And this is the file_get_contents_curl() function which is, I believe where the error is occurring and is where we need to catch the error.
function file_get_contents_curl($url){
$ch=curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
$cont = curl_exec($ch);
if(curl_error($ch))
{
die(curl_error($ch));
}
return $cont;
}
This is the error that is being generated:
connect() timed out!
This is the requested solution:
So the question is, how do I catch that error and have the file_get_contents_curl() function either return a zero or return a specific code that I can look for indicating quietly to my script that it failed to connect?
Upvotes: 0
Views: 825
Reputation: 23660
There are two timeout settings for cURL:
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); // Timeout in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 4); // Timeout in seconds
Set them both and cURL will fail gracefully on a timeout of either type.
However, slow DNS resolutions will trigger SIGALRM which cURL interprets as the timeout alarm. Add this to quiet that alarm, and any alarms that will halt the PHP execution:
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
You should continue to be checking for cURL errors and dealing with them, not suppressing them, like this:
$curl_errno = curl_errno($ch);
if ($curl_errno > 0) {
// Deal with error
}
Upvotes: 2
Reputation: 429
In PHP you can use @
to suppress any errors that are thrown. These errors will not be shown and the script will continue to execute. Just put @
in front of any line that you think causes the error.
You can put it here where you are calling the function
function get_tweets() {
$json_string = @file_get_contents_curl('https://urls.api.twitter.com/1/urls/count.json?url=' . $this->url); // This will not throw any errors if file_get_contents_curl() fails.
$json = json_decode($json_string, true);
return isset($json['count'])?intval($json['count']):0;
}
Or you can put it in your function, at any line where you think the error is caused.
Upvotes: 0