PHP RESTful

REST(英文:Representational State Transfer,簡稱REST) ,指的是一組架構(gòu)約束條件和原則。

符合REST設(shè)計風(fēng)格的Web API稱為RESTful API。它從以下三個方面資源進(jìn)行定義:

  • 直觀簡短的資源地址:URI,比如:http://example.com/resources/。
  • 傳輸?shù)馁Y源:Web服務(wù)接受與返回的互聯(lián)網(wǎng)媒體類型,比如:JSON,XML,YAM等。
  • 對資源的操作:Web服務(wù)在該資源上所支持的一系列請求方法(比如:POST,GET,PUT或DELETE)。

本教程我們將使用 PHP(不用框架) 來創(chuàng)建一個 RESTful web service,在文章末尾你可以下載本章節(jié)使用到的代碼。

通過本教程你將學(xué)習(xí)到以下內(nèi)容:

  • 創(chuàng)建一個 RESTful Webservice。
  • 使用原生 PHP, 不依賴任何框架。
  • URI 模式需要遵循 REST 規(guī)則。
  • RESTful service 接受與返回的格式可以是 JSON, XML等。
  • 根據(jù)不同情況響應(yīng)對應(yīng)的 HTTP 狀態(tài)碼。
  • 演示請求頭的使用。
  • 使用 REST 客戶端來測試 RESTful web service。

RESTful Webservice 實例

以下代碼是 RESTful 服務(wù)類 Site.php

實例

<?php
/* 
 * W3Cschool教程 RESTful 演示實例
 * RESTful 服務(wù)類
 */
Class Site {
    
    private 
$sites = array(
        
=> 'TaoBao',  
        
=> 'Google',  
        
=> 'W3CSchool',              
        
=> 'Baidu',              
        
=> 'Weibo',  
        
=> 'Sina'
            
    
);
        
    
    public function 
getAllSite(){
        return 
$this->sites;
    }
    
    public function 
getSite($id){
        
        
$site = array($id => ($this->sites[$id]) ? $this->sites[$id] : $this->sites[1]);
        return 
$site;
    }    
}
?>

RESTful Services URI 映射

RESTful Services URI 應(yīng)該設(shè)置為一個直觀簡短的資源地址。Apache 服務(wù)器的 .htaccess 應(yīng)設(shè)置好對應(yīng)的 Rewrite 規(guī)則。

本實例我們將使用兩個 URI 規(guī)則:

1、獲取所有站點(diǎn)列表:

http://localhost/restexample/site/list/

2、使用 id 獲取指定的站點(diǎn),以下 URI 為獲取 id 為 3 的站點(diǎn):

http://localhost/restexample/site/list/3/

項目的 .htaccess 文件配置規(guī)則如下所示:

# 開啟 rewrite 功能
Options +FollowSymlinks
RewriteEngine on

# 重寫規(guī)則
RewriteRule ^site/list/$   RestController.php?view=all [nc,qsa]
RewriteRule ^site/list/([0-9]+)/$   RestController.php?view=single&id=$1 [nc,qsa]

RESTful Web Service 控制器

.htaccess 文件中,我們通過設(shè)置參數(shù) 'view' 來獲取 RestController.php 文件中對應(yīng)的請求,通過獲取 'view' 不同的參數(shù)來分發(fā)到不同的方法上。RestController.php 文件代碼如下:

實例

<?php
require_once("SiteRestHandler.php");
        
$view "";
if(isset(
$_GET&#91;"view"&#93;))
    
$view $_GET&#91;"view"&#93;;
/*
 * RESTful service 控制器
 * URL 映射
*/
switch($view){

    case 
"all":
        
// 處理 REST Url /site/list/
        
$siteRestHandler = new SiteRestHandler();
        
$siteRestHandler->getAllSites();
        break;
        
    case 
"single":
        
// 處理 REST Url /site/show/<id>/
        
$siteRestHandler = new SiteRestHandler();
        
$siteRestHandler->getSite($_GET["id"]);
        break;

    case 
"" :
        
//404 - not found;
        
break;
}
?>

簡單的 RESTful 基礎(chǔ)類

以下提供了 RESTful 的一個基類,用于處理響應(yīng)請求的 HTTP 狀態(tài)碼,SimpleRest.php 文件代碼如下:

實例

<?php 
/*
 * 一個簡單的 RESTful web services 基類
 * 我們可以基于這個類來擴(kuò)展需求
*/
class SimpleRest {
    
    private 
$httpVersion "HTTP/1.1";

    public function 
setHttpHeaders($contentType$statusCode){
        
        
$statusMessage $this -> getHttpStatusMessage($statusCode);
        
        
header($this->httpVersion" "$statusCode ." "$statusMessage);        
        
header("Content-Type:"$contentType);
    }
    
    public function 
getHttpStatusMessage($statusCode){
        
$httpStatus = array(
            
100 => 'Continue',  
            
101 => 'Switching Protocols',  
            
200 => 'OK',
            
201 => 'Created',  
            
202 => 'Accepted',  
            
203 => 'Non-Authoritative Information',  
            
204 => 'No Content',  
            
205 => 'Reset Content',  
            
206 => 'Partial Content',  
            
300 => 'Multiple Choices',  
            
301 => 'Moved Permanently',  
            
302 => 'Found',  
            
303 => 'See Other',  
            
304 => 'Not Modified',  
            
305 => 'Use Proxy',  
            
306 => '(Unused)',  
            
307 => 'Temporary Redirect',  
            
400 => 'Bad Request',  
            
401 => 'Unauthorized',  
            
402 => 'Payment Required',  
            
403 => 'Forbidden',  
            
404 => 'Not Found',  
            
405 => 'Method Not Allowed',  
            
406 => 'Not Acceptable',  
            
407 => 'Proxy Authentication Required',  
            
408 => 'Request Timeout',  
            
409 => 'Conflict',  
            
410 => 'Gone',  
            
411 => 'Length Required',  
            
412 => 'Precondition Failed',  
            
413 => 'Request Entity Too Large',  
            
414 => 'Request-URI Too Long',  
            
415 => 'Unsupported Media Type',  
            
416 => 'Requested Range Not Satisfiable',  
            
417 => 'Expectation Failed',  
            
500 => 'Internal Server Error',  
            
501 => 'Not Implemented',  
            
502 => 'Bad Gateway',  
            
503 => 'Service Unavailable',  
            
504 => 'Gateway Timeout',  
            
505 => 'HTTP Version Not Supported');
        return (
$httpStatus[$statusCode]) ? $httpStatus[$statusCode] : $status[500];
    }
}
?>

RESTful Web Service 處理類

以下是一個 RESTful Web Service 處理類 SiteRestHandler.php,繼承了上面我們提供的 RESTful 基類,類中通過判斷請求的參數(shù)來決定返回的 HTTP 狀態(tài)碼及數(shù)據(jù)格式,實例中我們提供了三種數(shù)據(jù)格式: "application/json" 、 "application/xml" 或 "text/html":

SiteRestHandler.php 文件代碼如下:

實例

<?php 
require_once("SimpleRest.php");
require_once(
"Site.php");

class 
SiteRestHandler extends SimpleRest {

    function 
getAllSites() {    

        
$site = new Site();
        
$rawData $site->getAllSite();

        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,'text/html') !== false){
            
$response $this->encodeHtml($rawData);
            echo 
$response;
        } else if(
strpos($requestContentType,'application/xml') !== false){
            
$response $this->encodeXml($rawData);
            echo 
$response;
        }
    }
    
    public function 
encodeHtml($responseData) {
    
        
$htmlResponse "<table border='1'>";
        foreach(
$responseData as $key=>$value) {
                
$htmlResponse .= "<tr><td>"$key"</td><td>"$value"</td></tr>";
        }
        
$htmlResponse .= "</table>";
        return 
$htmlResponse;        
    }
    
    public function 
encodeJson($responseData) {
        
$jsonResponse json_encode($responseData);
        return 
$jsonResponse;        
    }
    
    public function 
encodeXml($responseData) {
        
// 創(chuàng)建 SimpleXMLElement 對象
        
$xml = new SimpleXMLElement('<?xml version="1.0"?><site></site>');
        foreach(
$responseData as $key=>$value) {
            
$xml->addChild($key$value);
        }
        return 
$xml->asXML();
    }
    
    public function 
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,'text/html') !== false){
            
$response $this->encodeHtml($rawData);
            echo 
$response;
        } else if(
strpos($requestContentType,'application/xml') !== false){
            
$response $this->encodeXml($rawData);
            echo 
$response;
        }
    }
}
?>

接下來我們通過 http://localhost/restexample/site/list/ 訪問,輸出結(jié)果如下:


RESTful Web Service 客戶端

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

實例中請求 http://localhost/restexample/site/list/ 地址,接收數(shù)據(jù)類似為 Accept: application/json

請求 id 為 3 的站點(diǎn) W3CSchool(W3Cschool教程),訪問地址為 http://localhost/restexample/site/list/3/,

源碼下載

實例中使用到的代碼可點(diǎn)擊以下按鈕下載:

源碼下載