闲话
已经两个月没有写简书了,百度地图实习这段时间还是深有体会的,虽然说实习的开发效率感觉不如一个人在学校时候开发效率高,但经过一个多月的实习,体验了一流互联网公司的开发流程,接触到了很多新的知识和框架,也认识了一些大牛们,深感追上他们还有很长的路要走。
说实话最近压力也很大,百度地图的开发任务和准备九,十月份的秋招,感觉时间很不够用,每天上下班在车上的时间都用来看书学习,相信以后的我回想起今天的努力不会感到遗憾,fighting!!!
cURL
为什么会突然学习这个模块?主要和最近的开发相关。百度地图和酷骑单车合作,我负责酷骑单车合作方的接入。也就是把端上传来的参数进行一定的处理后通过http请求传递到合作方的接口完成用车业务。而这部分最底层调用FetchUrl的模块就用到了cURL,利用下午加晚上的时间对这个模块进行了学习,趁睡前总结一下。
概述
cURL是一个非常强大的开源库,支持很多协议,包括HTTP、FTP、TELNET等,我们使用它来发送HTTP请求。它给我 们带来的好处是可以通过灵活的选项设置不同的HTTP协议参数,并且支持HTTPS。CURL可以根据URL前缀是“HTTP” 还是“HTTPS”自动选择是否加密发送内容。在PHP 4.0.2中被引入。
关于cURL的安装过程和条件网上有很多,这里就不再赘述了。但值得注意的是cURL的资源类型有两种——cURL句柄和cURL批处理句柄。cURL句柄简单说就是一次通过url进行请求的控制块,每个句柄包含了请求的url,header,method等信息,至于cURL批处理句柄,这里可以简单理解为多个控制块也就对应多个请求过程。
使用cURL发送请求的基本流程
还是发扬本人实践重于理解的一贯风格,使用cURL发送请求主要是四个步骤:
①初始化连接句柄
②设置cURL选项
③执行并得到结果
④释放cURL连接句柄
先来说说第一步,初始化连接句柄只需要执行一个init()函数即可,但这里要注意是单句柄还是批处理句柄。先来看看但句柄的初始化:
$ch = curl_init();
没错,就是这么简单。那么经过初始化之后句柄里包含了什么呢?查看句柄信息可以通过curl_getinfo()函数获得,通过var_dump()打印后如下所示:
array(26) {
["url"]=>
string(0) ""
["content_type"]=>
NULL
["http_code"]=>
int(0)
["header_size"]=>
int(0)
["request_size"]=>
int(0)
["filetime"]=>
int(0)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(0)
["namelookup_time"]=>
float(0)
["connect_time"]=>
float(0)
["pretransfer_time"]=>
float(0)
["size_upload"]=>
float(0)
["size_download"]=>
float(0)
["speed_download"]=>
float(0)
["speed_upload"]=>
float(0)
["download_content_length"]=>
float(-1)
["upload_content_length"]=>
float(-1)
["starttransfer_time"]=>
float(0)
["redirect_time"]=>
float(0)
["certinfo"]=>
array(0) {
}
["primary_ip"]=>
string(0) ""
["primary_port"]=>
int(0)
["local_ip"]=>
string(0) ""
["local_port"]=>
int(0)
["redirect_url"]=>
string(0) ""
}
就是一些请求的信息,可以看到有url、content_type等参数,只不过刚刚经过初始化的句柄什么信息都没有。
批处理句柄的创建需要基于单句柄来完成,毕竟是由多个单句柄组成的,示例如下:
//创建两个单句柄
$ch1 = curl_init();
$ch2 = curl_init();
...对两个单句柄进行选项设置...
//创建批处理句柄
$mh = curl_multi_init();
//添加单句柄
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
创建方式一目了然,不再赘述了。
第二步,设置选项,这步操作最为关键,涉及请求所使用的所有选项,例如url,method,请求参数等。所有设置操作都通过curl_setopt(resource $ch
, int $option , mixed $value)完成。假设现在有一个用户登录的请求,需要调用合作方的接口,url为'http://chuck_hu.com:8080/order/customer/login',需要的参数有手机号mobile和设备号cuid,请求方法为POST。那么就根据这些设置cURL句柄的选项。
//定义参数
$arrInput = array(
'mobile' => '1234567182',
'cuid' => '113ca2548b0a21b391af',
);
//定义url
$url = 'http://chuck_hu.com:8080/order/customer/login';
//初始化连接句柄
$ch = curl_init();
//设置curl选项
curl_setopt($ch, CURLOPT_URL, $url); //设置url
curl_setopt($ch, CURLOPT_POST, 1); //设置请求方法
curl_setopt($ch, CURLOPT_POSTFIELDS, $arrInput); //设置请求参数
诸如CURLOPT_URL、CURLOPT_POST的属性在PHP源码中是cURL模块的预定义常量,都是一些整形的数字,不用去管他,只要通过名称知道他控制什么选项即可。当我们再次var_dump(curl_getinfo($ch))时,就会发现原先的返回数组里面的一些选项发生了变化,比如url会边为'http://chuck_hu.com:8080/order/customer/login',设置也就完成了。接下来就是执行句柄请求获得结果了。
请求执行也分为单句柄和批处理句柄,这里只给出单句柄的请求执行,在cURL中curl_multi_xxx的方法即为批处理句柄方法,PHP开发手册上对每种方法都有详细说明。单句柄请求执行方式和初始化一样简洁:
$ret = curl_exec($ch);
返回值即为执行结果,此时再打印cURL句柄信息,会发现很多属性发生了变化:
array(26) {
["url"]=>
string(61) "http://chuck_hu.com:8080/order/customer/login"
["content_type"]=>
string(9) "text/html"
["http_code"]=>
int(200)
["header_size"]=>
int(424)
["request_size"]=>
int(222)
["filetime"]=>
int(-1)
["ssl_verify_result"]=>
int(0)
["redirect_count"]=>
int(0)
["total_time"]=>
float(0.058548)
["namelookup_time"]=>
float(0.004098)
["connect_time"]=>
float(0.004182)
["pretransfer_time"]=>
float(0.004186)
["size_upload"]=>
float(277)
["size_download"]=>
float(1837)
["speed_download"]=>
float(31375)
["speed_upload"]=>
float(4731)
["download_content_length"]=>
float(-1)
["upload_content_length"]=>
float(277)
["starttransfer_time"]=>
float(0.016705)
["redirect_time"]=>
float(0)
["certinfo"]=>
array(0) {
}
["primary_ip"]=>
string(12) "某ip"
["primary_port"]=>
int(8080)
["local_ip"]=>
string(12) "某ip"
["local_port"]=>
int(14091)
["redirect_url"]=>
string(0) ""
}
经过整个请求执行后,cURL句柄才算是一个完整的句柄,里面的一些属性是可以帮组我们去查看请求详情的,比如http_code就可以根据不同状态码得知请求完成情况。
接下来就是处理结果和释放连接了,释放连接只需要调用close方法:
curl_close($ch);
释放连接句柄很重要,不仅是释放资源,也体现了程序员的基本素养。
cURL就讲到这里,主要是对工作中发现的问题进行学习后的总结,以后要多钻研多总结。