PHP RESTful

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 => 'TaoBao', 2 => 'Google', 3 => 'itread01', 4 => 'Baidu', 5 => 'Weibo', 6 => '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 應該設定為一個直觀簡短的資源地址。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=$1 [nc,qsa]

RESTful Web Service 控制器

.htaccess 檔案中,我們通過設定引數 'view' 來獲取 RestController.php 檔案中對應的請求,通過獲取 'view' 不同的引數來分發到不同的方法上。RestController.php 檔案程式碼如下:

例項

<?php require_once("SiteRestHandler.php"); $view = ""; if(isset($_GET["view"])) $view = $_GET["view"]; /* * 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 基礎類

以下提供了 RESTful 的一個基類,用於處理響應請求的 HTTP 狀態碼,SimpleRest.php 檔案程式碼如下:

例項

<?php /* * 一個簡單的 RESTful web services 基類 * 我們可以基於這個類來擴充套件需求 */ 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 基類,類中通過判斷請求的引數來決定返回的 HTTP 狀態碼及資料格式,例項中我們提供了三種資料格式: "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) { // 建立 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/ 訪問,輸出結果如下:


RESTful Web Service 客戶端

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

例項中請求 http://localhost/restexample/site/list/ 地址,接收資料類似為 Accept: application/json

請求 id 為 3 的站點 itread01(入門教學),訪問地址為 http://localhost/restexample/site/list/3/,

原始碼下載

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

原始碼下載