闲话
已经两个月没有写简书了,百度地图实习这段时间还是深有体会的,虽然说实习的开发效率感觉不如一个人在学校时候开发效率高,但经过一个多月的实习,体验了一流互联网公司的开发流程,接触到了很多新的知识和框架,也认识了一些大牛们,深感追上他们还有很长的路要走。
说实话最近压力也很大,百度地图的开发任务和准备九,十月份的秋招,感觉时间很不够用,每天上下班在车上的时间都用来看书学习,相信以后的我回想起今天的努力不会感到遗憾,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就讲到这里,主要是对工作中发现的问题进行学习后的总结,以后要多钻研多总结。
作者:Chuck_Hu
链接:https://www.jianshu.com/p/53654d813708