PHP RESTful
REST(英文:Representational State Transfer,簡稱REST) ,指的是一組架構限制條件和原則。
符合REST設計風格的Web API稱為RESTful API。它從以下三個面向資源定義:
直覺簡短的資源位址:URI,例如:
http://example.com/resources/
。傳輸的資源:Web服務接受與傳回的網路媒體類型,例如:JSON,XML,YAM等。
對資源的運作:Web服務在該資源上所支援的一系列請求方法(例如:POST,GET,PUT或DELETE)。
本教學我們將使用 PHP(不用框架) 來建立一個 RESTful web service,在文章最後你可以下載本章節所使用的程式碼。
透過本教學你將學習到以下內容:
建立一個 RESTful Webservice。
使用原生 PHP, 不依賴任何框架。
URI 模式需要遵守 REST 規則。
RESTful service 接受與傳回的格式可以是 JSON, XML等。
根據不同情況回應對應的 HTTP 狀態碼。
示範請求頭的使用。
使用 REST 用戶端來測試 RESTful web service。
RESTful Webservice 實例
以下程式碼是 RESTful 服務類別 Site.php:
實例
#/*
* php中文網 RESTful 示範實例
* RESTful 服務類
*/
Class Site {
private $sites = array(
#1 ##=> 'Google'
, #3 =>
3 php', 4 ##
##5 => 'Weibo'#,
6 => ##1 #'Sina'
); return
$this
->
sites
; } 公用函數getSite($id#){
#= 數組($id => ($this->網站 [$id]) ? $this->網站[$id] : $this#->網站##[##1 ]); 返回 $site; }
#?>
#
RESTful Services URI 映射
RESTful Services URI 應該設定為直覺簡短的資源位址。 Apache 伺服器的 .htaccess 應設定好對應的 Rewrite 規則。
本實例我們將使用兩個URI 規則:
1、取得所有站點清單:
http://localhost/restexample/site/list/
2、使用id 取得指定的站點,以下URI 為取得id為3 的網站:
http://localhost/restexample/site/list/3/
專案的 .htaccess 檔案設定規則如下所示:
# 开启 rewrite 功能 Options +FollowSymlinks RewriteEngine on # 重写规则 RewriteRule ^site/list/$ RestController.php?view=all [nc,qsa] RewriteRule ^site/list/([0-9]+)/$ RestController.php?view=single&id= [nc,qsa]
RESTful Web Service 控制器
#在.htaccess 檔案中,我們透過設定參數'view' 來取得RestController.php 檔案中對應的請求,透過取得'view' 不同的參數來分發到不同的方法上。 RestController.php 檔案程式碼如下:
實例
#$view #= #""#;
if(isset(#) ##$_GET["檢視"]))
$view #= $_GET&##91;"檢視"];/*
* RESTful 服務控制器
* URL 對應
*/
#switch($view){
case
"all" :
// 處理 REST Url /site/list/
#"#$ ##();# $siteRestHandler->getAllSites
(); # # case "single":
#$siteRestHandler
= 新 #SiteRestHandler
(); $siteRestHandler->getSite($_GET##[ #"id"]); break;
case
#"" /404 - 未找到;
break;
}##?>
簡單的 RESTful 基礎類別
以下提供了 RESTful 的一個基類,用於處理回應請求的 HTTP 狀態碼,SimpleRest.php 檔案程式碼如下:
實例
#/*
* 一個簡單的 RESTful web services 基底類別
*我們可以基於這個類別來擴展需求
*/
class SimpleRest {
# private
##C $httpVersion
=
"HTTP/1.1"; public function setHttpHeaders($contentType, $statusCode
){
# ##$status## # = $this -> getHttpStatusMessage($statusCode##); header($this->
$this-> ##" ". $statusCode ." "
##.
$statusMessage); # header(## "##
##header######(## ###Content-Type:"####. ##$contentType######);### }### ### public function ######getHttpStatusMessage###############>> ##){### $httpStatus = 數組(
100 => '繼續' ,
#101 => #'切換協定』,
C #=> '好'##, 201
#, 202 ##=> '已接受「」
=> '非權威信息', 204
=> '無內容', # #205
#=> '重置內容'#, ##, # #206
=> '部分內容』, # #1 => '多項選擇'
, 301 ==> '永久移動',
302 #=> '找到',
# 303 => '看其他',
304 #=> '未修改',
# 305 #=> '使用代理程式',
# 306 #=> '(未使用)',
307 #=> '暫時重新導向',
400 #=> '錯誤請求',
401 #=> '未授權',
# 402 #=> 「需要付款」,
## 403 ==> '禁止',
## 404 #=> '找不到',
# 405 #=> '方法不允許',
406 #=> '不可接受',
407 => '需代理身分驗證',
408 #=> '請求逾時',
409 #=> '衝突',
## 410 #=> '離開了',
## 411 #=> '長度必要',
412 #=> 「前提條件失敗」,
413 ==> '請求實體太大',
414 #=> '請求 URI 太長',
#415 #=> '不支援的媒體類型',
#416 #=> '請求的範圍無法滿足',
#417 #=> '期望失敗',
# 500 => '內部伺服器錯誤',
501 #=> '未實施',
502 #=> '壞網關',
503 #=> '服務無法使用',
504 #=> '網關逾時',
505 ==> '不支援的HTTP 版本');
# return ($httpStatus[#$statusCode ])? $httpStatus[$statusCode] : ##$status[500]; }
}
?>
RESTful Web Service 處理類別
以下是一個RESTful Web Service 處理類別SiteRestHandler.php,繼承了上面我們提供的RESTful 基底類別,類別中透過判斷請求的參數來決定傳回的HTTP 狀態碼及資料格式,實例中我們提供了三種資料格式: "application/json" 、 "application/xml" 或"text/html":
SiteRestHandler.php # 檔案程式碼如下:
實例
#require_once("Site.php");
類別SiteRestHandler擴充功能 SimpleRest {
函數 getAllSites() {
# = 新 Site(); $rawData
= $site#$ ->getAllSite(); if(空白(
$rawData
#)) { #$statusCode
= 404# '錯誤'
=>'未找到網站! } else { #$statusCode # ##$requestContentType
= $_SERVER['HTTP_ACCEPT'#];
$this ->setHttpHeaders($requestContentType##, $statusCode);
if(
strpos($requestContentType,'application/json') !== false){
$response # # = $this->encodeJson($rawData); echo
$response##; } else if(strpos
(#$requestContentType#strpos($requestContentType##) ##strpos($requestContentType##) #,'text/html'##) !==
#false){ #response #response = $this->encodeHtml
($rawData
#####################################################。 #);#### echo ######$response######;### } $requestContentType######,######'application/xml'#######) !== ######false#####){### $response = $this->encodeXml( #$rawData);
echo $response;
##encodeHtml
(
##$responseData) { $htmlResponse#1
"
"
返回
$htmlResponse; } # 公用函數encodeJson($responseData){
$jsonResponse
#json_encode($responseData); 回傳
$jsonResponse
; } # 公用函數 encodeXml(
$responseData#### # #// 創建 SimpleXMLElement 對象#### ######$xml ######= new ######SimpleXMLElement######(######' xml version="1.0"?><site></site>'######);### foreach(######$responseData foreach(######$responseData ######as foreach(######$ ##$key######=>######$value######) {### ######$xmlxml#####-> ###addChild######(######$key######, ######$value######);### }## # }## # ######$xml######->######asXML######();### }### ### 公共函數 ### ### getSite######(######$id######) {###### $site = new Site();
$rawData = $site->getSite($id);
if(empty($rawData)) {
$statusCode = 404;
$rawData = array('error' => 'No sites found!');
} else {
$statusCode = 200;
}
$requestContentType = $_SERVER['HTTP_ACCEPT'];
$this ->setHttpHeaders($requestContentType##, $statusCode);
if(
strpos($requestContentType,'application/json') !== false){
$response # # = $this->encodeJson($rawData); echo
$response##; } else if(strpos
(#$requestContentType#strpos($requestContentType##) ##strpos($requestContentType##) #,'text/html'##) !==
#false){ #response #response = $this->encodeHtml
($rawData
#####################################################。 #);#### echo ######$response######;### } $requestContentType######,######'application/xml'#######) !== ######false#####){### $response = $this->encodeXml($rawData);
echo $response;
}
}
}
?>
接下來我們透過http://localhost/restexample/site/list/ 訪問,輸出結果如下:
##RESTful Web Service 用戶端接下來我們可以使用Google Chrome 瀏覽器的"Advance Rest Client" 作為RESTful Web Service 用戶端來請求我們的服務。 實例中請求http://localhost/restexample/site/list/ 位址,接收資料類似為
Accept: application/json
#