Heim >Backend-Entwicklung >PHP-Tutorial >php curl超时设置详解

php curl超时设置详解

WBOY
WBOYOriginal
2016-07-25 08:52:231385Durchsuche
本文介绍下,在php中使用curl时,进行超时设置的详细方法,大家参考下,希望对大家有一定的帮助。

访问HTTP方式很多,可以使用curl, socket, file_get_contents() 等方法。

在访问http时,需要考虑超时的问题。

一、CURL 访问HTTP CURL 是常用的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。

curl_setopt($ch, opt) 可以设置一些超时的设置,主要包括: *(重要) CURLOPT_TIMEOUT 设置cURL允许执行的最长秒数。 *(重要) CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。 (在cURL 7.16.2中被加入。从PHP 5.2.3起可使用)

CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。 CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。 (在cURL 7.16.2中被加入。从PHP 5.2.3开始可用)

CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,默认为120秒。

1,curl普通秒级超时:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_TIMEOUT,60); //只需要设置一个秒的数量就可以 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_USERAGENT, $defined_vars['HTTP_USER_AGENT']);

2,curl普通秒级超时使用:

curl_setopt($ch, CURLOPT_TIMEOUT,60);

3,curl如果需要进行毫秒超时,需要增加:

curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1L); //或者 curl_setopt ( $ch, CURLOPT_NOSIGNAL,true);//支持毫秒级别超时设置

curl超时设置的例子。

1,curl一个毫秒级超时的例子:

<?php
if(!isset($_GET['foo'])){  
        // Client  
        $ch = curl_init('http://example.com/');  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);  
        curl_setopt($ch, CURLOPT_NOSIGNAL,1);    //注意,毫秒超时一定要设置这个  
        curl_setopt($ch, CURLOPT_TIMEOUT_MS,200);  //超时毫秒,cURL 7.16.2中被加入。从PHP 5.2.3起可使用  
        $data = curl_exec($ch);  
        $curl_errno = curl_errno($ch);  
        $curl_error = curl_error($ch);  
        curl_close($ch);  
   
        if($curl_errno >0){  
                echo "cURL Error ($curl_errno): $curl_error\n";  
        }else{  
                echo "Data received: $data\n";  
        }  
}else{  
        // Server  
        sleep(10);  
        echo "Done.";  
}  

技巧: 1,cURL 版本 >= libcurl/7.21.0 版本,毫秒级超时是一定生效的,切记。 2,curl_multi的毫秒级超时的问题,单次访问是支持ms级超时的,curl_multi并行调多个会不准。

二、流处理方式访问HTTP 除了curl,还经常使用fsockopen、或file操作函数来进行HTTP协议的处理。 下面说说这方面的超时设置。

一般连接超时可以直接设置,但是流读取超时需要单独处理。 可以参考以下实现代码:

<?php
$tmCurrent = gettimeofday();  
       $intUSGone =($tmCurrent['sec']- $tmStart['sec'])*1000000  
                  +($tmCurrent['usec']- $tmStart['usec']);  
       if($intUSGone > $this->_intReadTimeoutUS){  
           returnfalse;  
       }  

或使用内置流处理函数 stream_set_timeout() 和 stream_get_meta_data() 处理:

<?php
// Timeout in seconds   
$timeout =5;   
$fp = fsockopen("example.com",80, $errno, $errstr, $timeout);if($fp){   
        fwrite($fp,"GET / HTTP/1.0\r\n");   
        fwrite($fp,"Host: example.com\r\n");   
        fwrite($fp,"Connection: Close\r\n\r\n");   
        stream_set_blocking($fp,true);   //重要,设置为非阻塞模式  
        stream_set_timeout($fp,$timeout);   //设置超时  
        $info = stream_get_meta_data($fp);   
        while((!feof($fp))&&(!$info['timed_out'])){   
                $data .= fgets($fp,4096);   
                $info = stream_get_meta_data($fp);   
                ob_flush;   
                flush();   
        }   
        if($info['timed_out']){   
                echo "Connection Timed Out!";   
        }else{   
                echo $data;   
        }}  

file_get_contents 超时:

<?php
$timeout = array(  
    'http'=> array(  
        'timeout'=>5//设置一个超时时间,单位为秒  
    )  
);  
$ctx = stream_context_create($timeout);  
$text = file_get_contents("http://example.com/",0, $ctx);  

fopen 超时:

<?php
$timeout = array(  
   'http' => array(  
       'timeout' => 5 //设置一个超时时间,单位为秒  
   )  
);  
  
$ctx = stream_context_create($timeout);  
  
if ($fp = fopen("http://example.com/", "r", false, $ctx)) {  
 while( $c = fread($fp, 8192)) {  
   echo $c;  
 }  
 fclose($fp);  
}  


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn