## REST介紹
REST(Representational State Transfer表述性狀態轉移)是一種針對網絡應用的設計和開發方式,可以降低開發的復雜性,提高系統的可伸縮性。REST提出了一些設計概念和準則:
1、網絡上的所有事物都被抽象為資源(resource);
2、每個資源對應一個唯一的資源標識(resource identifier);
3、通過通用的連接器接口(generic connector interface)對資源進行操作;
4、對資源的各種操作不會改變資源標識;
5、所有的操作都是無狀態的(stateless)。
需要注意的是,REST是設計風格而不是標準。REST通常基于使用HTTP,URI,和XML以及HTML這些現有的廣泛流行的協議和標準。
傳統的請求模式和REST模式的請求模式區別:
| 作用 | 傳統模式 | REST模式 |
|-----|-----|-----|
| 列舉出所有的用戶 | GET /users/list | GET /users |
| 列出ID為1的用戶信息 | GET /users/show/id/1 | GET /users/1 |
| 插入一個新的用戶 | POST /users/add | POST /users |
| 更新ID為1的用戶信息 | POST /users/mdy/id/1 | PUT /users/1 |
| 刪除ID為1的用戶 | POST /users/delete/id/1 | DELETE /users/1 |
> 經過老楊在freelog里的rest實踐 發現TP里I方法不支持`I('delete.')` 這種,只能獲取get參數。
關于更多的REST信息,可以參考:[http://zh.wikipedia.org/wiki/REST](http://zh.wikipedia.org/wiki/REST)
## RESTFul支持
3.2的RESTFul支持更為靈活,你只需要把控制器繼承Think\Controller\RestController即可。 繼承RestController控制器后你的訪問控制器就可以支持下面的一些功能:
> - 支持資源類型自動檢測;
> - 支持請求類型自動檢測;
> - RESTFul方法支持;
> - 可以設置允許的請求類型列表;
> - 可以設置允許請求和輸出的資源類型;
> - 可以設置默認請求類型和默認資源類型;
例如:
~~~
namespace Home\Controller;
use Think\Controller\RestController;
class BlogController extends RestController{
}
~~~
## REST參數
繼承了RestController后,你可以在你的控制器里面設置rest相關的屬性參數,包括:allowMethod,defaultMethod,allowType,defaultType以及allowOutputType。
| 屬性名 | 說明 | 默認值 |
|-----|-----|-----|
| allowMethod | REST允許的請求類型列表 | array('get','post','put','delete') |
| defaultMethod | REST默認請求類型 | get |
| allowType | REST允許請求的資源類型列表 | array('html','xml','json','rss') |
| defaultType | REST默認的資源類型 | html |
| allowOutputType | REST允許輸出的資源類型列表 | array( 'xml' => 'application/xml', 'json' => 'application/json','html' => 'text/html',) |
## REST方法
RESTFul方法的操作方法定義主要區別在于,需要對請求類型和資源類型進行判斷,大多數情況下,通過路由定義可以把操作方法綁定到某個請求類型和資源類型。如果你沒有定義路由的話,需要自己在操作方法里面添加判斷代碼,示例:
~~~
namespace Home\Controller;
use Think\Controller\RestController;
Class InfoController extends RestController {
Public function rest() {
switch ($this->_method){
case 'get': // get請求處理代碼
if ($this->_type == 'html'){
}elseif($this->_type == 'xml'){
}
break;
case 'put': // put請求處理代碼
break;
case 'post': // post請求處理代碼
break;
}
}
}
~~~
> 在Rest操作方法中,可以使用$this->_type獲取當前訪問的資源類型,用$this->_method獲取當前的請求類型。
REST控制器類還提供了response方法用于REST輸出: 用法如下:
~~~
$this->response($data,'json');
~~~
Response方法會自動對data數據進行輸出類型編碼,目前支持的包括`xml/json/html`。
除了普通方式定義Restful操作方法外,系統還支持另外一種自動調用方式,就是根據當前請求類型和資源類型自動調用相關操作方法。系統的自動調用規則是:
| 定義規范 | 說明 |
|-----|-----|
| 操作名_提交類型_資源后綴 | 標準的Restful方法定義,例如 read_get_pdf |
| 操作名_資源后綴 | 當前提交類型和defaultMethod屬性相同的時候,例如read_pdf |
| 操作名_提交類型 | 當前資源后綴和defaultType屬性相同的時候,例如read_post |
要使用這種方式的前提就是不能為當前操作定義方法,這樣在空操作的檢查之前系統會首先按照上面的定義規范順序檢查是否存在方法定義,如果檢測到相關的restful方法則不再檢查后面的方法規范,例如我們定義了InfoController如下:
~~~
namespace Home\Controller;
use Think\Controller\RestController;
Class InfoController extends RestController {
protected $allowMethod = array('get','post','put'); // REST允許的請求類型列表
protected $allowType = array('html','xml','json'); // REST允許請求的資源類型列表
Public function read_get_html(){
// 輸出id為1的Info的html頁面
}
Public function read_get_xml(){
// 輸出id為1的Info的XML數據
}
Public function read_xml(){
// 輸出id為1的Info的XML數據
}
Public function read_json(){
// 輸出id為1的Info的json數據
}
}
~~~
如果我們訪問的URL是:
~~~
http://www.domain.com/Info/read/id/1.xml
~~~
假設我們沒有定義路由,這樣訪問的是Info控制器的read操作,那么上面的請求會調用InfoController類的 `read_get_xml`方法,而不是`read_xml`方法,但是如果訪問的URL是:
~~~
http://www.domain.com/Info/read/id/1.json
~~~
那么則會調用read_json方法。
如果我們訪問的URL是
~~~
http://www.domain.com/Info/read/id/1.rss
~~~
由于我們不允許rss資源類型的訪問,所以,調用的方法其實是read_html方法。
## REST路由
我們可以借助3.2的路由參數功能,來解決REST的路由定義問題。 例如,
~~~
'blog/:id'=>array('blog/read','status=1',array('ext'=>'xml','method'=>'get')),
~~~
上面的路由定義,把blog/5路由到了blog/read/id/5 并且,約束了后綴是xml 請求類型是get。 我們還可以定義其他的路由參數,例如:
~~~
'blog/:id'=>array('blog/update','',array('ext'=>'xml','method'=>'put')),
~~~
為了確保定義不沖突,REST路由定義我們通常改成下面的定義方式:
~~~
array('blog/:id','blog/read','status=1',array('ext'=>'xml','method'=>'get')),
array('blog/:id','blog/update','',array('ext'=>'xml','method'=>'put')),
~~~
> 這樣就可以給相同的路由規則定義不同的參數支持。定義了REST路由后,你的rest方法定義就不受任何約束,當然,如果路由定義的操作方法不存在的時候,系統默認的rest方法規范仍然會有效。
- 序
- 前言
- 內容簡介
- 目錄
- 基礎知識
- 起步
- 控制器
- 模型
- 模板
- 命名空間
- 進階知識
- 路由
- 配置
- 緩存
- 權限
- 擴展
- 國際化
- 安全
- 單元測試
- 拿來主義
- 調試方法
- 調試的步驟
- 調試工具
- 顯示trace信息
- 開啟調試和關閉調試的區別
- netbeans+xdebug
- Socketlog
- PHP常見錯誤
- 小黃鴨調試法,每個程序員都要知道的
- 應用場景
- 第三方登錄
- 圖片處理
- 博客
- SAE
- REST實踐
- Cli
- ajax分頁
- barcode條形碼
- excel
- 發郵件
- 漢字轉全拼和首字母,支持帶聲調
- 中文分詞
- 瀏覽器useragent解析
- freelog項目實戰
- 需求分析
- 數據庫設計
- 編碼實踐
- 前端實現
- rest接口
- 文章發布
- 文件上傳
- 視頻播放
- 音樂播放
- 圖片幻燈片展示
- 注冊和登錄
- 個人資料更新
- 第三方登錄的使用
- 后臺
- 微信的開發
- 首頁及個人主頁
- 列表
- 歸檔
- 搜索
- 分頁
- 總結經驗
- 自我提升
- 進行小項目的鍛煉
- 對現有輪子的重構和移植
- 寫技術博客
- 制作視頻教程
- 學習PHP的知識和新特性
- 和同行直接溝通、交流
- 學好英語,走向國際
- 如何參與
- 瀏覽官網和極思維還有看云
- 回答ThinkPHP新手的問題
- 嘗試發現ThinkPHP的bug,告訴官方人員或者push request
- 開發能提高效率的ThinkPHP工具
- 嘗試翻譯官方文檔
- 幫新手入門
- 創造基于ThinkPHP的產品,進行連帶推廣
- 展望未來
- OneThink
- ThinkPHP4
- 附錄