curl_multi_exec与curl_exec
/*
CURLOPT_CONNECTTIMEOUT用来告诉PHP脚本在成功连接服务器前等待多久(连接成功之后就会开始缓冲输出),这个参数是为了应对目标服务器的过载,下线,或者崩溃等可能状况;
CURLOPT_TIMEOUT 用来告诉成功PHP脚本,从服务器接收缓冲完成前需要等待多长时间。如果目标是个巨大的文件,生成内容速度过慢或者链路速度过慢,这个参数就会很有用。
CURL 是常用的访问HTTP协议接口的lib库,性能高,还有一些并发支持的功能等。
curl_setopt($ch, opt) 可以设置一些超时的设置,主要包括:
① (重要) CURLOPT_TIMEOUT 设置cURL允许执行的最长秒数。
② (重要) CURLOPT_TIMEOUT_MS 设置cURL允许执行的最长毫秒数。
③ CURLOPT_CONNECTTIMEOUT 在发起连接前等待的时间,如果设置为0,则无限等待。
④ CURLOPT_CONNECTTIMEOUT_MS 尝试连接等待的时间,以毫秒为单位。如果设置为0,则无限等待。 (curl_setopt($conn, CURLOPT_NOSIGNAL,1);)
⑤ CURLOPT_DNS_CACHE_TIMEOUT 设置在内存中保存DNS信息的时间,0不缓存,-1永久缓存,默认120s
*/
$urls = array(
"http://192.168.33.10:815/swoole/swoole_call/sleep.php",
'sleep' => "http://192.168.33.10:815/swoole/swoole_call/sleep.php",
'test' => "http://www.data13.com",
);
$timeBegin=explode('.',microtime(true));
$timeBeginFloat=microtime(true);
echo 'curl begin '.date('Y-m-d H:i:s',$timeBegin[0]).'.'.$timeBegin[1];
$curlMulti=curlMulti($urls);
$timeEnd=explode('.',microtime(true));
echo ' curl end '.date('Y-m-d H:i:s',$timeEnd[0]).'.'.$timeEnd[1].',total exec time '.bcsub(microtime(true),$timeBeginFloat,4);
var_dump($curlMulti);
echo '<hr>';
$timeBegin=explode('.',microtime(true));
$timeBeginFloat=microtime(true);
echo 'curl begin '.date('Y-m-d H:i:s',$timeBegin[0]).'.'.$timeBegin[1];
$curlOneRst=[];
foreach($urls as $k=>$v){
$curlOneRst[]=curlOne($v);
}
$timeEnd=explode('.',microtime(true));
echo ' curl end '.date('Y-m-d H:i:s',$timeEnd[0]).'.'.$timeEnd[1].',total exec time '.bcsub(microtime(true),$timeBeginFloat,4);
var_dump($curlOneRst);
function curlMulti($urls){
$ch = array();
$res = array();
$conn = array();
// 创建批处理cURL句柄
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i]=curlInit($url);
// 增加句柄
curl_multi_add_handle($mh, $conn[$i]);
}
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (($multiSelect=curl_multi_select($mh)) != -1) {
usleep(100);
}
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
/*
if (($multiSelect=curl_multi_select($mh)) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
*/
}
foreach ($urls as $i => $url) {
//获取请求头信息
//$heards = curl_getinfo($conn[$i]);
//var_dump($heards);
//获取输出的文本流
$res[$i] = curl_multi_getcontent($conn[$i]);
// 移除curl批处理句柄资源中的某个句柄资源
curl_multi_remove_handle($mh, $conn[$i]);
//关闭cURL会话
curl_close($conn[$i]);
}
//关闭全部句柄
curl_multi_close($mh);
return $res;
}
function curlOne($url){
$conn=curlInit($url);
$response = curl_exec($conn);
if ($response === FALSE) {
$error = curl_error($conn) . ' [' . curl_errno($conn) . ']';
}
$headers = curl_getinfo($conn); //CURLINFO_HEADER_SIZE
//关闭cURL会话
curl_close($conn);
return $response;
}
function curlInit($url){
// 创建cURL资源
$conn = curl_init();
// 设置URL和相应的选项
curl_setopt($conn, CURLOPT_URL, $url);
curl_setopt($conn, CURLOPT_RETURNTRANSFER,1);
curl_setopt($conn, CURLOPT_DNS_CACHE_TIMEOUT,0);
curl_setopt($conn, CURLOPT_TIMEOUT,5);
curl_setopt($conn, CURLOPT_NOSIGNAL,1);
curl_setopt($conn, CURLOPT_CONNECTTIMEOUT_MS,300);
return $conn;
}
sleep.php
sleep(1);
$rst=['status'=>200,'msg'=>'ok'];
echo json_encode($rst);
参考
understanding php curl_multi_exec
https://stackoverflow.com/questions/15559157/understanding-php-curl-multi-exec
Doing curl_multi_exec the right way
http://www.adrianworlddesign.com/Knowledge-Base/php/Download-content-with-cURL/Doing-curlmultiexec-the-right-way
PHP and curl_multi_exec
http://technosophos.com/2012/10/26/php-and-curlmultiexec.html
php curl_multi_exec 官网例子里面为啥有两次 do while
https://segmentfault.com/q/1010000005159193
curl_multi_select解决curl_multi网页假死问题
https://www.cnblogs.com/chunguang/p/5895174.html
php curl 批量请求
https://blog.csdn.net/u013372487/article/details/51956996
php中curl同时发送多个请求curl_multi函数集的用法
https://blog.csdn.net/xueling022/article/details/51907990