找到你要的答案

Q:How can I catch this PHP connection error?

Q:我怎样才能抓住这个PHP连接错误?

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?

这里的问题:

在一些网站上,我的代码连接到推特产生一个致命的错误,停止运行的PHP页面加载的休息。它创建了一个总页面杀死。我怎样才能抓住这个错误,我可以简单地显示零或使用一个从以往的成功连接的微博数量?

大概,这是因为有这个代码的网站已经碰到了Twitter API限制。但在罕见的情况下,这确实发生了,我需要它优雅地失败,这样我就可以使用我以前的鸣叫鸣叫计数。

这是代码:

如果用户有Twitter按钮激活,我们获取的份额计数:

$social = new shareCount($url);
if( $options['twitter'] ) $tweets = $social->get_tweets();

这就是功能要求通过在sharecount类:

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;
}

这是file_get_contents_curl()函数是,我相信在错误的发生,是我们需要捕获错误。

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;
}

这是正在生成的错误:

connect() timed out!

这是请求的解决方案:

所以问题是,我如何抓住错误和有file_get_contents_curl()函数返回一零或返回一个特定的代码,我可以找我的脚本,它静静地显示连接失败?

answer1: 回答1:

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
}

有两个超时设置卷曲:

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4);        // Timeout in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 4);               // Timeout in seconds

设置他们和卷曲将失败优雅地在任一类型的超时。

然而,缓慢的DNS决议将触发SIGALRM卷曲解释为超时报警。这个安静的,报警,和任何警报,将停止PHP执行:

curl_setopt($ch, CURLOPT_NOSIGNAL, 1);

你应该继续检查卷曲错误并处理它们,而不是压制它们,像这样:

$curl_errno = curl_errno($ch);
if ($curl_errno > 0) {
    // Deal with error
}
answer2: 回答2:

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.

在PHP中可以使用@来抑制任何错误被抛出。不会显示这些错误,脚本将继续执行。只要放在任何你认为导致错误的线前面。

你可以把它放在你调用函数的地方

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;
}

或者你可以把它放在你的函数中,在任何你认为是错误的行。

php  curl