php 实现curl 多请求和异步请求
记录一下后台请求外部接口时的几个常用场景
/**
* 普通访问
* @param $url :访问的URL,
* @param $post :post数据(不填则为GET),
* @param $cookie :提交的$cookies,
* @param $returnCookie :是否返回$cookies
* */
public static function curl_request($url, $post = '', $cookie = '', $returnCookie = 0)
{
$headers = [];
if (is_array($post)) {
$post = json_encode($post);
}
$header = array('Content-Type' => 'application/x-www-form-urlencoded', 'Access-Control-Allow-Origin:*');
foreach ($header as $key => $value) {
$headers[] = $key . ":" . $value;
}
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
// curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
// curl_setopt($curl, CURLOPT_REFERER, "http://XXX");
if ($post) {
curl_setopt($curl, CURLOPT_POST, false);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
}
if ($cookie) {
curl_setopt($curl, CURLOPT_COOKIE, $cookie);
}
curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
//https请求 不验证证书和host
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($curl);
if (curl_errno($curl)) {
return curl_error($curl);
}
curl_close($curl);
if ($returnCookie) {
list($header, $body) = explode("\r\n\r\n", $data, 2);
preg_match_all("/Set-Cookie:([^;]*);/", $header, $matches);
$info['cookie'] = substr($matches[1][0], 1);
$info['content'] = $body;
return $info;
} else {
return $data;
}
}
/**
* 异步请求
* @param $url
* @param array $param
*/
public static function asyncRequest($url, $param = array())
{
// ignore_user_abort(true); // 忽略客户端断开
// set_time_limit(0); // 设置执行不超时
$urlinfo = parse_url($url);
$host = $urlinfo['host'];
$path = $urlinfo['path'];
$query = isset($param) ? http_build_query($param) : '';
$port = 80;
$errno = 0;
$errstr = '';
$timeout = 10;
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
$out = "POST " . $path . " HTTP/1.1\r\n";
$out .= "host:" . $host . "\r\n";
$out .= "content-length:" . strlen($query) . "\r\n";
$out .= "content-type:application/x-www-form-urlencoded\r\n";
$out .= "connection:close\r\n\r\n";
$out .= $query;
fputs($fp, $out);
fclose($fp);
}
/**
* 同时多个curl
* @param array $url_array
* @param int $wait_usec
* @param string $cookie
* @param string $return_type
* @return array|false
*/
public static function async_get_urls(array $url_array, int $wait_usec = 10, string $cookie = '' , string $return_type = 'array')
{
if (!is_array($url_array)) {
return false;
}
$defaults = [];
$wait_usec = intval($wait_usec);
$data = array();
$handle = array();
$running = 0;
$mh = curl_multi_init();
$i = 0;
foreach ($url_array as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Accept-Encoding" => "gzip, deflate, br", "Connection" => "keep-alive", "Host" => "webcast3-normal-c-hl.amemv.com", "Content-Type" => "application/json;charset=utf-8"]);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
//curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_MAXREDIRS, 7);
$protocol = substr($url, 0, 5);
if ('https' == $protocol) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
curl_multi_add_handle($mh, $ch);
$handle[$i++] = $ch;
}
do {
curl_multi_exec($mh, $running);
if ($wait_usec > 0) {
usleep($wait_usec);
}
} while ($running > 0);
foreach ($handle as $i => $ch) {
$content = curl_multi_getcontent($ch);
$data[$i] = (curl_errno($ch) == 0) ? $content : false;
if( $return_type == 'array')
$data[$i] = json_decode($data[$i], true);
}
foreach ($handle as $ch) {
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
return $data;
}