PHP使用REST API

1. 什么是REST API

REST(Representational State Transfer)翻译为“表现层状态转化”。表现层其实就是资源
REST是Web的基础架构原则。客户端(浏览器)和服务器可以以复杂的方式进行交互,而客户端无需事先了解服务器及其承载的资源。主流使用的两个请求资源的动作是 GETPOST

我们的服务使用基于JSON的自定义超媒体,我们为其分配了mimetype application / json 可能还有application / xml 或者 application /  可能支持许多媒体类型)。

REST API 使用了所有描述性的方式来定义用于表示资源和驱动应用程序的请求方式和请求响应类型。
API编程通过遵循5种基本软件架构风格原则,以任何编程语言编写Web应用程序:

》资源(数据,信息)
》唯一的全局标识符(所有资源都是由URI标识的唯一标识)
》统一接口 - 使用简单和标准接口(HTTP)
》表示 - 所有通信都通过表示(例如XML / JSON)完成
》无状态(每个请求都完全隔离,缓存和负载平衡更容易)


通过URL请求资源

协议仅限于使用URL进行通信的内容。
元数据作为键值对(post 数据 和查询字符串参数)传递。

》REST支持者倾向于支持URL,例如 即 pathinfo模式的传参

》REST架构不需要这些“漂亮的URL”。如:带参数的GET请求

部分详情可参见: https://blog.csdn.net/maxiao124/article/details/79897229


2. REST API资源请求方式

我们可能常常见到
GET | POST
如下:

www.example.com/user?id=1
www.example.com/user/id/1
www.example.com/user/get/id/1
www.example.com/user/delete/id/1
www.example.com/user/delete?id=1
www.example.com/user/edit?id=1
www.example.com/user/edit/id/1


或者 POST

www.example.com/user/sava
form-data
name=zhangsan&age=12

好了,很熟悉是吧。根据上面请求资源的链接,我们可能很清楚的从字面意思上了解到,这个带delete 做删除的,

那个是带edit做修改的,这个啥都不带查询的... 

如果我们完全使用上面的方式,比如说 GET 方式访问

www.example.com/user/delete?id=1


如果粗心的后端没有做登录或者权限方面的限制,被人知道了链接,或者被搜索引擎进行了抓取访问,那整个用户表估计都被清空了。

所以REST API中的资源请求,定义了CURD完整的描述性请求方式,

POST    www.example.com/user/id/1   增
DELETE  www.example.com/user/id/1   删
PUT     www.example.com/user/id/1   改
GET     www.example.com/user/id/1   查


其他请求方式: OPTIONS | HEAD | PUT | DELETE | TRACE | CONNECT | PATCH (HTTP1.1好像已废弃)

HEAD:仅返回相应头部,不包含Body

TRACE:对数据传输过程进行诊断

OPTIONS:请求 Web 服务器告知其支持的各种功能

按照REST 语义请求的方式我们可以看到下面的例子

POST来创建一个新用户

POST /user
Accept: application/json
Content-Type: application/json

{
    "name": "zhangsan",
    "country": "USA"
}

响应

200 OK
Content-Type: application/json

{
    "error":0, 
    "message": "add ok "
}

PUT 修改数据

PUT /user/1
Accept: application/json
Content-Type: application/json

{
    "name": "lisi",
    "country": "USA"
}

响应

200 OK
Content-Type: application/json

{
    "error":0, 
    "message": "update ok "
}


DELETE 删除用户数据
请求

DELETE /user/1
Accept: application/json

响应

200 OK
Content-Type: application/json

{
    "error":0, 
    "message": "delete ok "
}


GET 查询用户数据

GET /user/1
Accept: application/json

响应

200 OK
Content-Type: application/json

{
    "error":0, 
    "data": {
            "id": 1,
            "name": "lisi",
            "country: "USA"
        }
}

当然,上面请求参数和响应接收的参数类型,不一定是json,还可以是text/htmlxmlform-data等等
这取决于响应的字段 Content-Type,接收的类型则取决于 Accept

如果考虑到安全问题,我们可以在请求头信息中约定某个字段,作为获取资源的凭证 ticket,比如:

Auth-Token : ZI-GEea1KgfxnnDmKAAAAVjnsTKe0OE4vMOBWCtOcrB-56YcrhOHMho

这里有个完整的REST API栗子:环信REST API


3. 请求方式在服务端的使用

获取请求方法:

$method = $_SERVER['REQUEST_METHOD'];

服务端接收请求数据:

GET   

$params = $_GET ; //或者 $_REQUEST 可以多个地方使用

POST  

$params = $_POST ; //或者 $_REQUEST

DELETE PUT PATCH OPTIONS TRACE CONNECT 

parse_str(file_get_contents('php://input'), $params);  //仅能使用一次 再次使用将会显示为空值

有没有谁想过请求方式是否可以自定义?我试了一下,居然可以。

尝试写一个ajax

$.ajax({
    type: "EDIT",
    url: "/index/test",
    data: {name: "zhangsan"},
    success: function (returnVal) {
        console.log(returnVal)
    }
});

浏览器请求头出现了

EDIT /index/test HTTP/1.1
Host:127.0.0.1
Connection: keep-alive
Content-Length: 13

name=zhagnsan

而且正常响应200,服务端对应的方法打印出 请求方法为 EDIT
当然 参数只能使用 

file_get_contents('php://input')

如果我们仅仅是路由方式传参,可以通过如下获取pathinfo 信息

$path_info = $_SERVER['PATH_INFO'];

【注意】; CURD语义请求方法中 GET,DELETE不包含BODY,PUT, POST可以包含BODY。而如果一个谓词包含了语义之外的操作,例如GET中带BODY,POST用于删除资源这种操作也是被允许的,称之为方式重载,虽然HTTP可以支持方式重载,但并不建议使用,因为不符合标准语义,EDIT都没上标准,更加不建议使用,估计是为了扩展。

PHP CURL 模拟请求 各种方法

/**
 * @todo:支持rest请求的curl 
 *    包括 GET POST DELETE PUT
 */
function multiCurl($url,$body,$header,$type="POST"){
		//1.创建一个curl资源
		$ch = curl_init();
		//2.设置URL和相应的选项
		curl_setopt($ch,CURLOPT_URL,$url);//设置url
		//1)设置请求头
		//设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
		curl_setopt($ch,CURLOPT_HEADER,0);
//		curl_setopt ( $ch, CURLOPT_TIMEOUT,5); // 设置超时限制防止死循环
		//设置发起连接前的等待时间,如果设置为0,则无限等待。
		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,5);
		//将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		//2)设备请求体
		if (count($body)>0) {
			//$b=json_encode($body,true);
			curl_setopt($ch, CURLOPT_POSTFIELDS, $body);//全部数据使用HTTP协议中的"POST"操作来发送。
		}
		//设置请求头
		//array_push($header, 'Accept:application/json');
		//array_push($header,'Content-Type:application/json');
		//array_push($header, 'http:multipart/form-data');
		if(count($header)>0){
			curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
		}
		//上传文件相关设置
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算
		
		//3)设置提交方式
		switch($type){
			case "GET":
				curl_setopt($ch,CURLOPT_HTTPGET,true);
				break;
			case "POST":
				curl_setopt($ch,CURLOPT_POST,true);
				break;
			case "PUT"://使用一个自定义的请求信息来代替"GET"或"HEAD"作为HTTP请求。这对于执行"DELETE" 或者其他更隐蔽的HTT
				curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"PUT");
				break;
			case "DELETE":
				curl_setopt($ch,CURLOPT_CUSTOMREQUEST,"DELETE");
				break;
		}
		
		
		//4)在HTTP请求中包含一个"User-Agent: "头的字符串。-----必设
	
//		curl_setopt($ch, CURLOPT_USERAGENT, 'SSTS Browser/1.0');
//		curl_setopt($ch, CURLOPT_ENCODING, 'gzip');
	
		curl_setopt ( $ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)' ); // 模拟用户使用的浏览器
		//5)
		
		
		//3.抓取URL并把它传递给浏览器
		$res=curl_exec($ch);
		$result=json_decode($res,true);
		//4.关闭curl资源,并且释放系统资源
		curl_close($ch);
		if(empty($result))
			return $res;
		else
			return $result;
	
	}

本文仅仅是基于PHP对rest的简单认知,如果想深入,可以参考这篇 论文

议题参考来自:Stack Overflow


 

猜你喜欢

转载自blog.csdn.net/wujiangwei567/article/details/81359855