前言
因为项目需要检测代理的状态和获取代理后的ip和地理位置,耗时等信息
过程
方法传值$ proxy()是数组存放代理连接信息,
$url我传的是自己项目里面检测ip的接口,访问我的接口然后拿到地理位置还有耗时一举两得
$mh是在在外面初始化cURL批处理句柄
话不多说直接上代码
$url = 'http://******';
//额,我测试本地环境一次检测超过两百个左右就不行了,所以分批一次200
for ($i=0;count($proxy)>0;$i++){
//初始化cURL批处理句柄
$mh = curl_multi_init();
//一次拿两百个去检测
$checkProxy = array_splice($proxy,0,200);
//方法
$this->batchCheckProxy($checkProxy,$url,$mh);
}
public function batchCheckProxy($proxy,$url,$mh)
{
$conn = array();
foreach ($proxy as $key => $value){
$conn[$key]['curl'] = curl_init(); //初始化各个子连接
$conn[$key]['id'] = $value['id']; //顺便加个ip的id进去,方便后面修改他的状态
//设置url和相应的选项
curl_setopt ($conn[$key]['curl'], CURLOPT_CONNECTTIMEOUT, 1); //设置在发起连接前等待的最长时间,因为不设置是无限等待所以还是设置一下
curl_setopt ($conn[$key]['curl'], CURLOPT_RETURNTRANSFER, 1); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出
curl_setopt ($conn[$key]['curl'], CURLOPT_TIMEOUT, 1); //cURL允许执行的最长秒数
curl_setopt($conn[$key]['curl'], CURLOPT_PROXY, $value['ip']); //使用代理ip
curl_setopt($conn[$key]['curl'], CURLOPT_PROXYPORT, $value['port']); //代理ip的端口
curl_setopt($conn[$key]['curl'], CURLOPT_PROXYUSERPWD, $value['user'].':'.$value['password']); //检测的http代理是带账密的,不需要的同学把这一行去掉即可
curl_setopt($conn[$key]['curl'], CURLOPT_URL, $url); //需要获取的URL地址
curl_setopt($conn[$key]['curl'], CURLOPT_HEADER, 0);
curl_setopt($conn[$key]['curl'], CURLOPT_RETURNTRANSFER, 1);; //不直接输出到浏览器,而是返回字符串
curl_multi_add_handle($mh, $conn[$key]['curl']); //增加 ch 句柄到批处理会话mh
}
$active = null; //连接数
//防卡死写法:执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
//这个循环的目的是尽可能地读写,直到无法继续读写为止
//返回 CURLM_CALL_MULTI_PERFORM 表示还能继续向网络读写
} while($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($conn as $k => $ch) {
$result = curl_multi_getcontent($ch['curl']); //返回获取的输出的文本流
$getInfo = curl_getinfo($ch['curl']);
curl_multi_remove_handle($mh,$ch['curl']); //从给定的批处理句柄mh中移除ch句柄
curl_close($conn[$k]['curl']); //关闭cURL 会话并且释放所有资源
//返回的文本不是string0就说明连上
if (empty($result)) {
IpLibraryModel::updateInfo(['status'=>0],['id'=>$ch['id']]);
}else{
$ipData = json_decode($result,true);
IpLibraryModel::updateInfo([
'status' => 1,
'country' => $ipData['countryCode'],
'region' => $ipData['region'],
'city' => $ipData['city'],
'ping' => $getInfo['total_time'],
'ext' => $result
],['id'=>$ch['id']]);
}
}
curl_multi_close($mh); //关闭一组cURL句柄
}