[转]拙议REST及其在PHP中的现状

简介: 本文并不想从头介绍REST,只是想举例说明在HTTP中使用REST需要注意的问题:先来看看人们对REST的困惑: REST长啥样? 最一般的REST例子,类似下面的样子: POST   /articles     ...
本文并不想从头介绍REST,只是想举例说明在HTTP中使用REST需要注意的问题:

先来看看人们对REST的困惑

REST长啥样?

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

POST   /articles     创建
DELETE /articles/123 删除
PUT    /articles/123 更新或创建
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对类似问题的解决方案是:创建一个新的资源!在上面的例子里,我们可以这样:

PUT /top_articles/123

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

如何设计资源的URL?

最常见的资源命名方式是/controllers/id,不过这不是必须的,REST并没有强制规定URL必须符合哪种形式,你大可以按照自己的设想去自由的设计,实际编程时大致有两种方法:

一种是基于路径变量的命名,如:/china/beijing/laowang

基于路径变量的命名方式一般用来描述具有层次化的结构的资源。

另一种是基于查询变量的命名,如:/person?name=laowang

基于查询变量的命名方式一般用来描述某种算法的计算结果。

到底是使用基于路径的命名方式,还是基于查询的命名方式,取决于你看问题的角度和个人的喜好。

REST反对使用Session么?

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

但也有人认为,现在可以很方便的把session存储在memcached之类的分布式缓存中,所以不是问题。

Cookie对REST有害么?

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

再来看看REST在PHP中的现状

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

CakePHP:

设定路由:

Router::parseExtensions('xml');
Router::mapResources('articles');

编写控制器:

class ArticlesController extends AppController {

var $components = array('RequestHandler');

function view($id = null) {
$article = $this->Article->findById($id);
$this->set(compact('article'));
}

// ...
}

视图:

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

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

POST   /articles
DELETE /articles/123.xml
PUT    /articles/123.xml
GET    /articles/123.xml

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

参考链接:

http://book.cakephp.org/view/476/rest
http://c7y.phparch.com/c/entry/1/art,cakephp-rest

ZendFramework:

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

服务端:

require_once 'Zend/Rest/Server.php';

function sayHello($who, $when)
{
return "Hello $who, Good $when";
}

$server = new Zend_Rest_Server();
$server->addFunction('sayHello');
$server->handle();

客户端:

require_once 'Zend/Rest/Client.php';

$client = new Zend_Rest_Client('http://path/to/server/script');
$client->sayHello('Davey', 'Day');

echo $client->get();

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

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伪 实现。

参考链接:

http://framework.zend.com/manual/en/zend.rest.html
http://framework.zend.com/manual/en/zend.xmlrpc.html

=============================

此外,还有几篇不错的文章:

http://www.berenddeboer.net/rest/
http://www.ibm.com/developerworks/webservices/library/ws-restful/
http://www.infoq.com/cn/articles/rest-architecure
http://www.infoq.com/cn/articles/rest-introduction
http://www.infoq.com/cn/articles/rest-anti-patterns
http://www.infoq.com/cn/articles/webber-rest-workflow
http://www.infoq.com/cn/articles/tilkov-rest-doubts
http://www.infoq.com/cn/articles/designing-restful-http-apps-roth
http://www.infoq.com/cn/articles/roa-rest-of-rest
目录
相关文章
|
程序员 API PHP
REST API教程(PHP)
很高兴有人能看到这篇博客!我希望你已经做好心理准备,在这里我们将从0开始构建REST API。这不是一件简单的事情:我们接下来要做很多事情,不仅仅是coding还包括去理清一些理论知识。但我向你保证,你会为你付出努力而感到高兴。
1368 0
|
2月前
|
安全 关系型数据库 MySQL
PHP与MySQL交互:从入门到实践
【9月更文挑战第20天】在数字时代的浪潮中,掌握PHP与MySQL的互动成为了开发动态网站和应用程序的关键。本文将通过简明的语言和实例,引导你理解PHP如何与MySQL数据库进行对话,开启你的编程之旅。我们将从连接数据库开始,逐步深入到执行查询、处理结果,以及应对常见的挑战。无论你是初学者还是希望提升技能的开发者,这篇文章都将为你提供实用的知识和技巧。让我们一起探索PHP与MySQL交互的世界,解锁数据的力量!
|
2月前
|
NoSQL 关系型数据库 MySQL
不是 PHP 不行了,而是 MySQL 数据库扛不住啊
【9月更文挑战第8天】这段内容讨论了MySQL在某些场景下面临的挑战及其原因,并指出这些问题不能完全归咎于MySQL本身。高并发读写压力、数据量增长以及复杂查询和事务处理都可能导致性能瓶颈。然而,应用程序设计不合理、系统架构不佳以及其他数据库选择和优化策略不足也是重要因素。综合考虑这些方面才能有效解决性能问题,而MySQL通过不断改进和优化,仍然是许多应用场景中的可靠选择。
124 9
|
3月前
|
存储 SQL 关系型数据库
PHP与MySQL交互的奥秘
【8月更文挑战第29天】在编程的世界里,PHP和MySQL就像是一对默契的舞伴,共同演绎着数据的交响曲。本文将带你探索它们之间的互动,从连接数据库到执行查询,再到处理结果,每一步都充满了节奏与和谐。我们将一起走进这段代码的旅程,感受数据流动的魅力。
|
5天前
|
存储 关系型数据库 MySQL
PHP与MySQL动态网站开发深度解析####
本文作为技术性文章,深入探讨了PHP与MySQL结合在动态网站开发中的应用实践,从环境搭建到具体案例实现,旨在为开发者提供一套详尽的实战指南。不同于常规摘要仅概述内容,本文将以“手把手”的教学方式,引导读者逐步构建一个功能完备的动态网站,涵盖前端用户界面设计、后端逻辑处理及数据库高效管理等关键环节,确保读者能够全面掌握PHP与MySQL在动态网站开发中的精髓。 ####
|
6天前
|
关系型数据库 MySQL PHP
PHP与MySQL动态网站开发实战指南####
本文深入探讨了PHP与MySQL在动态网站开发中的应用实践,通过具体案例解析如何高效结合这两大技术构建数据驱动的Web应用。文章将涵盖环境搭建、基础语法回顾、数据库设计与操作、用户注册与登录系统实现等关键步骤,旨在为开发者提供一个从零到一的项目实战路径,展示PHP与MySQL协同工作的强大能力。 ####
|
25天前
|
SQL 关系型数据库 MySQL
PHP与MySQL协同工作的艺术:开发高效动态网站
在这个后端技术迅速迭代的时代,PHP和MySQL的组合仍然是创建动态网站和应用的主流选择之一。本文将带领读者深入理解PHP后端逻辑与MySQL数据库之间的协同工作方式,包括数据的检索、插入、更新和删除操作。文章将通过一系列实用的示例和最佳实践,揭示如何充分利用这两种技术的优势,构建高效、安全且易于维护的动态网站。
|
3月前
|
SQL 关系型数据库 MySQL
PHP与MySQL交互之基础教程
【8月更文挑战第31天】 在数字世界中,数据是推动一切的核心力量。本文将引导你探索PHP与MySQL的协同工作,通过实际代码示例,展示如何建立连接、执行查询以及处理结果集。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你提供宝贵的实践知识。
|
4月前
|
数据库
基于PHP+MYSQL开发制作的趣味测试网站源码
基于PHP+MYSQL开发制作的趣味测试网站源码。可在后台提前设置好缘分, 自己手动在数据库里修改数据,数据库里有就会优先查询数据库的信息, 没设置的话第一次查询缘分都是非常好的 95-99,第二次查就比较差 , 所以如果要你女朋友查询你的名字觉得很好 那就得是她第一反应是查和你的缘分, 如果查的是别人,那不好意思,第二个可能是你。
66 3
下一篇
无影云桌面