curl - http请求

  • 作者:KK

  • 发表日期:2017.8.23


前提知识准备

  1. 了解https的基本意思和配置方法,可参考文章《Apache2.4 - 常用基础 - https主机配置

  2. 最好能进一步了解ssl证书链机制

  3. 主要涉及CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOSTCURLOPT_CAINFO这三个选项


例1:对自己颁发证书的https站点发请求

这种站点由于不是权威机构颁发的证书,浏览器会提示不安全,请求代码如下:

function httpsRequest($url, $postData = [], $timeout = 30){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout - 2);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //信任任何证书
	if(version_compare(curl_version()['version'], '7.10') == -1){
		//如果php编译时引用的cURL版本小于7.10就强制设为2,因为它默认为1,不安全
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //这个选项的意思是:检查证书中的域名和请求的域名是否一致,设为0表示不检查,这个都不检查的话,本次请求仅仅产生传输加密作用,对数据接收方是谁是不管的了
	}
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect:']); //避免params数据过长问题
	if($postData){
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
	}
	$result = curl_exec($ch);
	if($errorNo = curl_errno($ch)){
		throw new Exception($errorNo . ': ' . curl_error($ch));
	}
	curl_close($ch);
	return $result;
}

echo httpsRequest('https://test');

例2:对CA权威机构颁发证书的站点发请求

function httpsRequest($url, $postData = [], $timeout = 30){
    $cacert = getcwd() . '/cacert.pem'; //根证书文件,比如支付宝、微信支付,他们会配上这个根证书的嘛
	
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout - 2);
	
	//如果直对某些站点做采集你可能要仿一下浏览器,自己选择
	$agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.2141.400 QQBrowser/9.5.10219.400';
	curl_setopt($ch, CURLOPT_USERAGENT, $agent);

	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);   // 只信任CA颁布的证书  
	curl_setopt($ch, CURLOPT_CAINFO, $cacert); //设定CA根证书,验证网站的ssl证书是否是由这个CA根证书所属的威权机构颁发的
	if(version_compare(curl_version()['version'], '7.10') == -1){
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
	}
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	if($postData){
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
	}
	$result = curl_exec($ch);
	if($errorNo = curl_errno($ch)){
		throw new Exception($errorNo . ': ' . curl_error($ch));
	}
	curl_close($ch);
	return $result;
}

echo httpsRequest('https://test');