PHP网络技术(三)——CURL实现跨服务取接口功能

PHP网络技术(三)——CURL实现跨服务取接口功能

(原创内容,转载请注明来源,谢谢)

PHP的curl类库,可以实现远程访问、页面抓取、表单提交、文件上传、本地服务访问等,功能强大而调用方式简单。

一、curl请求

PHP的curl请求包括四个部分:

1、初始化curl句柄。

         $ch= curl_init();

2、对curl句柄进行选项的设置,包括url、参数、最大连接数等。

         curl_setopt($ch,CURLOPT_URL, ‘127.0.0.1/test.php?name=”a”’);
         curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch,CURLOPT_HEADER, 1);

3、执行curl,获取返回值(HTML形式)。

         $result= curl_exec($ch);
         if(false=== $result){
         $err = curl_error($ch);
}

4、释放curl句柄。

         curl_close($ch);

具体解释:

1)首先,初始化curl,只需要一个init的函数即可。返回值是PHP的resource类型变量。

2)接着,设置选项。setopt函数很重要,几个关键的设置关系到curl执行和返回的全过程。

主要的设置如下:

a.CURLOPT_AUTOREFERER:当curl执行的返回需要重定向时,设置此选项可以让重定向过程自动设置header信息,以便于重定向。

b.CURLOPT_COOKIESESSION:使用此选项,可以限制仅发送一个session cookie,而不发送其他的cookie。session cookie是指存放用户session的cookie,用于标记用户的session状况,可以验证是否登陆等信息。

c.CURLOPT_RETURNTRANSFER:指定exec函数执行后,返回的是文件流格式,而不是直接在屏幕输出。

d.CURLOPT_HTTPHEADER:设定HTTP头字段组成的数组,形式array(‘Content-type:text/plain’, ‘Content-length:1024’)

e.CURLOPT_INFILE:设定上传文件的文件地址。

f.CURLOPT_POSTFIELDS:全部数据使用HTTP协议的POST发送,要求要发送的文件前面用@字符并且是完整路径,参数要求用urlencoded方法加密,并且把信息转换成字符串’para1=val1&para2=val2…’的形式。

g.CURLOPT_MAXCONNECTS:允许最大连接数量。

3)第三步,是执行curl,用exec函数可以执行,并且有返回结果。同时,如果执行失败,则返回false,可以用error获取到错误详情。

需要注意的是,要用===(全等,值与类型都相等)符号判断是否是false,反之返回空字符串、数字0或者空数组被判定为false。

4)最后,用close关闭curl的句柄,结束curl连接。

另外,可以用curl_getinfo($ch)放在exec函数执行之后,返回执行此次curl操作的各项关键信息数组,如http状态码、请求大小、请求耗时、上传下载数据大小与速度、跳转次数等。

二、curl发送post请求,实现简单跨服务请求

如果要发送get类型的请求,可以用file_get_contents()来实现。但是,post请求,由于不是在url后面加后缀,无法拼接出url来,因此需要用curl的方式来发送请求。

1、程序需求

当项目较大,存在多个系统,系统之间错综复杂,则往往需要用到RPC,将系统之间独立部署,做服务化项目。此时,不同系统之间将采用接口调用的方式实现功能。

例如,现有一个购物网站,则存在用户管理系统、物品管理系统、购物流程管理系统、支付系统等。对于用户购物付款,其实用户系统的角色仅仅是提供用户ID、用户基本信息,对于用户购物这件事本身并没有什么用处。

另外,当用户量巨大、物品也很多、购物订单也非常频繁时,这几个表必定是数据量极大的表,且查询、新增等操作非常频繁。此时,则需要将这些表按照业务场景划分到不同的数据库中,且由不同的文件去进行独立的sql交互工作。

为了避免用户系统改进(如新增一个权限等)出现的一些bug影响到整个网站的购物,则可以将用户系统独立出来,单独进行维护。

此时,则可以将原先和用户相关的业务场景独立出来,例如对用户信息的查询、用户个人信息的修改,在用户系统的相关文件中提供接口(即提供对内网开放的类以及相应的方法),在其他场景要用到的时候可以调用此接口。

2、curl实现post发送请求

调用方式则采用curl的方式,发送请求,并得到反馈的消息。

下面的程序用curl实现简单的请求发送与反馈。请求执行端的代码比较简单,不罗列出来,即采用$_POST的方式接收请求(也可以用户自定义其他方式),并进行一些处理。发送端通过curl发送请求。

本示例实现一个curl的简单处理类,可以通过curl发送post请求。具体代码如下。

         <?php
class CurlDealer{
     private $ch;//句柄
     public function__construct(){
              $this->ch =curl_init();
     }
     //初始化
     public functioninitCurl(){
              if(null == $ths->ch){
                       $this->ch= curl_init();
              }
     }
     //设置参数
     public functionsetOpt(array $arr){         
              if(null ==$this->ch || empty($arr)){
                       returnfalse;
              }
              foreach($arr as$opt){
                       //遍历进行配置
                       curl_setopt($this->ch,$opt[0], $opt[1]);
              }
     }
     //执行curl
     public functionexecCurl(){
              if($this->ch){
                       $res =curl_exec($this->ch);
                       if(false=== $res){
                                 returncurl_error($this->ch);
                       }
                       return$res;                       
              }else{
                       returnnull;
              }
     }
     //获取执行后的curlinfo
     public functiongetCurlInfo(){
              if($this->ch){
                       returncurl_getinfo($this->ch);
              }else{
                       returnnull;
              }
     }
     //关闭curl
     public functioncloseCurl(){
              if($this->ch){
                       curl_close($this->ch);
                       $this->ch= null;
              }
     }
}
$ch = new CurlDealer();
$arrOpt = array(
     array(CURLOPT_URL,'http://127.0.0.1/phpnet/index.php'),
     array(CURLOPT_RETURNTRANSFER,1),
     array(CURLOPT_POST, 1),
     array(CURLOPT_POSTFIELDS,array('comment'=>'curl'))
);
$ch->setOpt($arrOpt);
$res = $ch->execCurl();
var_dump($res);
$ch->closeCurl();

3、评价

1)优势

独立性——curl的方式发送请求,相比于原先的new一个类的实例,再执行里面的方法,最大的好处在于实现了各个系统之间的独立。上面所说的购物场景,用户系统可以相当于一个完全独立的系统,对于支付系统的开发人员来说,甚至可以认为和支付宝、微信等提供的API一样,是一个外部的系统。

因此,支付系统的开发人员可以专注于支付系统的开发与维护,不用考虑用户系统的类是否有问题,new以后会不会出现意外的情况等。而如果需要一些新的方法,用户系统中没有,则可以和用户系统的人协商,再写一个接口实现相应的方法,同样简单便捷。

轻量级——curl发送请求,只请求一个接口,并不需要new整个类,也不需要去考虑底层的实现方式,就像使用curl不需要考虑curl如何实现(但是如果要考虑性能优化,则需要了解其如何实现,目的是为了更好的运用curl),使得程序变得轻量级,易于维护。

2)缺点

网络资源——curl最大的缺点在于网络资源占用问题。每次执行一个curl_exec()函数,相当于发送一次http请求,而且对方处理完还要再发送回来,这样对资源的花销还是比较大。因此在满足业务场景的需求下,尽量少使用curl,以节约网络资源。

沟通成本——当系统庞大而且需要拆分时,沟通成本增加是必然的情况。但是这也是为了业务能够更好的推进,因此这个算是一个双刃剑。

——written by linhxx 2017.07.22

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-07-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏扎心了老铁

redis的发布订阅模式pubsub

前言 redis支持发布订阅模式,在这个实现中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端),而是将信息发送给频道(chann...

2807
来自专栏后端技术探索

PHP并发IO编程之路

并发IO问题一直是后端编程中的技术挑战,从最早的同步阻塞Fork进程,到多进程/多线程,到现在的异步IO、协程。PHP程序员因为有强大的LAMP框架,对底层方面...

661
来自专栏即时通讯技术

微信自用高性能通用key-value组件MMKV已开源!

腾讯微信团队于2018年9月底宣布开源 MMKV ,这是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,...

942
来自专栏后端技术探索

PHP并发IO编程之路

并发IO问题一直是后端编程中的技术挑战,从最早的同步阻塞Fork进程,到多进程/多线程,到现在的异步IO、协程。PHP程序员因为有强大的LAMP框架,对底层方面...

613
来自专栏决胜机器学习

优化页面访问速度(一)——综述

优化页面访问速度,首先需要了解用户在浏览器输入url后,最终是如何看到所需的页面。在了解整个流程后,可以逐个步骤进行优化。

994
来自专栏圣杰的专栏

ABP入门系列(13)——Redis缓存用起来

源码路径:Github-LearningMpaAbp 1. 引言 创建任务时我们需要指定分配给谁,Demo中我们使用一个下拉列表用来显示当前系统的所有用户,以...

2329
来自专栏重庆的技术分享区

【翻译】使用Akka HTTP构建微服务:CDC方法

1353
来自专栏PHP技术

PHP并发IO编程之路

原文出处: 韩天峰(@韩天峰-Rango) 并 发IO问题一直是后端编程中的技术挑战,从最早的同步阻塞Fork进程,到多进程/多线程,到现在的异步IO、协程。...

3737
来自专栏java达人

防止表单重复提交的思路和方法

作为一个软件开发者,绝不能奢望你的用户会规规矩矩地使用你的软件,他们一般都是缺乏耐心,“胡作非为”的。比如当他点击提交表单时,服务器处理比较慢, 页面上没有任何...

1838
来自专栏即时通讯技术

微信自用高性能通用key-value组件MMKV已开源!

腾讯微信团队于2018年9月底宣布开源 MMKV ,这是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,...

732

扫码关注云+社区