REST介绍与REST在PHP中的应用

当HTTP被发明出来的时候,其实REST就已经存在了。可惜这么多年来,WEB开发模式却越来越背离HTTP的本质,舍本逐末的追求起RPC之类的东西。此时REST重新回到人们的视线里,无疑让大家开始反思过去走过的弯路。

本文并不想从头介绍REST,只是想举例说明一下需要注意的问题:

先来看看人们对REST的困惑:

REST什么样子?

最一般的REST例子,类似下面的样子:

1 POST   /articles     创建
2 DELETE /articles/123 删除
3 PUT    /articles/123 更新或创建
4 GET    /articles/123 查看

顺便说说几个知识点:

GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有 变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定 的服务端逻辑造成的。

PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。顺便说一句,因为GET操作是安全的,所以它自然也是幂等的。

POST操作既不是安全的,也不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。

安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。

还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/articles), 而PUT操作是作用在一个具体资源之上的(/articles/123),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确 定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用 POST。

浏览器不支持PUT/DELETE方法怎么办?

大部分浏览器只支持GET/POST方法,这使得我们无法完美的实现REST。对于这样的情况,大致有几种解决方法,一种是在表单里加入一个 _method之类名字的隐藏字段,用于表示真正的方法,另一种是使用X-HTTP-METHOD-OVERRIDE头信息来重载POST。

HTTP方法够用么?

从上面的例子,我们可以看到,通过使用已有的HTTP方法:POST,DELETE,PUT,GET就可以完成资源的增删改查,但在实际情况 中,我们需要做的操作往往并不仅仅局限在简单的增删改查操作中,比如说我们要把一篇文章“置顶”,但是HTTP方法里没有一个和“置顶”操作相对应的方 法,这时候该怎么办呢?REST对类似问题的解决方案是:创建一个新的资源!在上面的例子里,我们可以这样:

1 PUT /toparticles/123

通过创建出一个新的资源(toparticles),我们就可以使用简单的HTTP方法通吃一切操作了。

REST反对使用Session么?

牢记一点,REST拒绝Session!这是因为REST强调无状态性。这里的状态指的的应用状态,也可以称之为会话状态。一旦在服务端保持了这样的状态,那么架构的可扩展性将大打折扣。在REST看来,任何类似的状态本身都应该是一个独立的资源。

Cookie对REST有害么?

一分为二的看,如果Cookie里保存的是应用状态的话,就没有问题。因为应用状态本来就属于客户端。但如果使用Cookie保存类似PHPSESSIONID之类的东西就不对了,因为这样的数据并不属于客户端状态,它只不过是使用Session的借口而已。

再来看看REST在PHP中的现状:

PHP里的REST实现案例不多,有点影响都就是CakePHP和Zend,下面分别看看他们的实现:

CakePHP:

设定路由:

1 Router::parseExtensions(‘xml‘);
2 Router::mapResources(‘articles‘);

编写控制器:

1 class ArticlesController extends AppController {
2     var $components = array(‘RequestHandler‘);
3     function view($id = null) {
4         $article = $this->Article->findById($id);
5         $this->set(compact(‘article‘));
6     }
7     // ...
8 }

视图:

1 <articles>
2 <?php echo $xml->serialize($article); ?>
3 </articles>

差不多就这样了,相应的,还可以实现其他的功能,于是,如下REST操作便成为可能:

1 POST   /articles
2 DELETE /articles/123.xml
3 PUT    /articles/123.xml
4 GET    /articles/123.xml

总体看,CakePHP的REST实现基本上是按Rails风格来实现的,大体还过得去。

ZendFramework:

ZendFramework通过Zend_Rest组件来实现Rest功能:

服务端:

1 require_once ‘Zend/Rest/Server.php‘;
2 function sayHello($who, $when)
3 {
4     return "Hello $who, Good $when";
5 }
6 $server = new Zend_Rest_Server();
7 $server->addFunction(‘sayHello‘);
8 $server->handle();

客户端:

1 require_once ‘Zend/Rest/Client.php‘;
2 $client = new Zend_Rest_Client(http://path/to/server/script);
3 $client->sayHello(‘Davey‘, ‘Day‘);
4      
5 echo $client->get();

这时候,我们看一下Web服务器的日志,会发现生成了一条如下的记录:

1 GET /path/to/servier/script?method=sayHello&arg0=Davey&arg1=Day&rest=1 HTTP/1.1

我们发现,实际操作方法是由URL中的method=sayHello指定的,而HTTP固有方法(GET/POST等)则成为了摆设,这是典 型的RPC风格,如果大家对比Zend_Rest和Zend_XmlRpc文档的话,会明显发现它们根本就是一个东西,所以说,Zend_Rest是一个 REST伪实现。

这个基本 REST 设计原则建立了创建、读取、更新和删除(create, read, update, and delete,CRUD)操作与 HTTP 方法之间的一对一映射。 根据此映射:
1)若要在服务器上创建资源,应该使用 POST 方法。
2)若要检索某个资源,应该使用 GET 方法。
3)若要更改资源状态或对其进行更新,应该使用 PUT 方法。
4)若要删除某个资源,应该使用 DELETE 方法。

时间: 2024-10-24 20:15:47

REST介绍与REST在PHP中的应用的相关文章

介绍几个C++程序中关于&quot;时间&quot;的函数

时间,我们每天都在与之打交道. 程序的世界中更是,时间无处不在. 在你编写程序的时候,很多时候需要获取当前的时间,并且进行格式化输出,所以心血来潮,就想着整理搜集几个关于"时间"的函数. 但是需要强调一点,本博客里所介绍的函数都是C++语言中的. time函数 原型: time_t time (time_t* timer); 作用: Get the current calendar time as a value of type time_t. The function returns

J哥--------------------------分享好东西:android抓包工具fiddler使用介绍 抓取 手机APP 中资源。

本文地址:http://blog.csdn.net/u011733020 首先,写这个只是为了学习,不是要做什么违法的事情,如果有问题,有关部门 请联系我,立马删除. 不要查我水表. 正题:这里介绍 抓包的关键,Fiddler  ,Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯. 我们就是用这款软件抓取 ,我们手机app 访问的 资源路径 的. 下面 我们拿实例 来演示下,怎么用fiddler 抓取数据.(以某拍为例吧). 环境: win7

简单介绍下怎么在spring中使用RabbitMQ

这篇文章主要介绍了简单了解如何在spring中使用RabbitMQ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 常见的消息中间件产品: (1)ActiveMQ ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现. (2)RabbitMQ AMQP协议的领导实现,支持多种场景.淘宝的MySQL集群内部有使用它进行通讯,Open

iOS边练边学--NSURLSession、NSURLSessionTask的介绍与使用以及url中包含了中文的处理方法

一.NSURLSession.NSURLSessionTask的使用步骤 首先创建NSURLSession对象 通过NSURLSession对象创建对应的任务 <1>NSURLSessionDataTask的GET和POST  -- 以及url中包含了中文的解决办法 <2>NSURLSessionDownloadTask实现小文件的下载 <3>NSURLSessionDownloadTask实现大文件的断点下载 -- 暂时没有实现退出程序后的文件续传 1 #import

19.C#逐一介绍IEnumerable和IEnumerable&lt;T&gt;中的扩展方法(10.3-10.5)

今天没有太多的言语,只有代码,扩展方法多得太多,不能一一列完,书中一些,看多了也就会使用了. 1 //Enumerable.Range 返回起始到结束范围,是一个Enumrable<int>类型 2 //Range方法并不会真的构造含有适当数字的列表,它只是在恰当的时间生成那些数,"just in time" 3 var c0 = Enumerable.Range(1, 10); 4 foreach (var e in c0) 5 { 6 Console.WriteLine

Coredump介绍及如何在Android中开启和使用来分析Crash等问题

文章目录: Coredump简介及使用... 1 目录... 2 一.什么是Coredump. 3 二.Coredump产生的原因... 3 三.如何控制产生Coredump. 4 四.使用Coredump的准备... 4 五.开始使用Coredump. 5 一.什么是Coredump 有些C/C++程序或者通过JNI调用了C/C++的APK程序可以通过编译, 但在运行时会出现错误,比如常见的signal 11 (SIGSEGV),这样的程序都是可以通过编译的,而且这样的错误一般情况下不会像编译

介绍EF提供的3中查询方式

這邊簡單介紹一下,ADO.Net Entity Framework 提供的三種查詢方式, Linq to Entities Query Builder Mothed Entity SQL Language [Linq to Entities] Linq to Entities 是最常見的語法,也是用最多的,  來看一個範例 1 ////示範 Linq to Enities 2 using (TestEntities te = new TestEntities()) 3 { 4     var u

javascript介绍及如何在html中使用js与jQuery

js是世界上最流行的编程语言,这一点毋庸置疑:它是一种弱类型,动态脚本编程语言,被广泛用于HTML,web技术中. 啰嗦:一直在学后端技术,现在发现js基本上不会用,因为现在不使用jsp做前端页面,所以到处都是js对静态页面的封装,然后实现前后端交互.现在发现js功能真强大啊,可以对页面各种修改,真是前端一个js技术就够了. 其实当我看到一大堆js的页面时,脑子是懵的,完全不知道它该怎么执行,但是他跟其他编程语言也是类似的,有函数,变量等等.好了不废话了. 一.js在HTML中的使用: 1.js

Android 中常见控件的介绍和使用

1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.lang.Object   ? android.view.View   ? android.widget.TextView 直接子类: Button, CheckedTextView, Chronometer, DigitalClock, EditText 间接子类: AutoCompleteTextV