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
#/* 
 * php中文網 RESTful 示範實例
 * RESTful 服務類
 */
Class Site {
    
    private 
$sites = array(
        
#1  ##=> 'Google'
,  
        #3 => 
php',                      ## 
        
##5 => 'Weibo'#,  
        
=> ##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 檔案程式碼如下:

實例

require_once("SiteRestHandler.php" #) ;
        
#$view #= #""#;
if(isset(
#) ##$_GET&#91;"檢視"]))    
$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 檔案程式碼如下:

實例

<?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("SimpleRest.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
"
"";#        foreach($responseData as ##$$
$responseData 
as ##$$ key=>$value) {                 $ ;tr><td>"
。 $鍵。 "</td><td>"。 $值。 "</td></tr>";        }       "
"
;
        返回 
$htmlResponse;            }    #    公用函數encodeJson$responseData){
        
$jsonResponse









#json_encode($responseData);        回傳 

$jsonResponse
;            }    #    公用函數 encodeXml(

$responseData####  # #// 創建 SimpleXMLElement 對象####        ######$xml ######= new ######SimpleXMLElement######(######'<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/ 訪問,輸出結果如下:

restful1.jpg


##RESTful Web Service 用戶端

接下來我們可以使用Google Chrome 瀏覽器的"Advance Rest Client" 作為RESTful Web Service 用戶端來請求我們的服務。

實例中請求http://localhost/restexample/site/list/ 位址,接收資料類似為

Accept: application/json

restful2.jpg

請求id 為3 的網站php(php中文網),存取位址為http://localhost/restexample/site/list/3/,

restful3.jpg

來源碼下載

實例中使用到的程式碼可點選下列按鈕下載:

原始碼下載


#