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:
實例
/*
* W3Cschool教程 RESTful 演示實例
* RESTful 服務(wù)類
*/
Class Site {
private $sites = array(
1 => 'TaoBao',
2 => 'Google',
3 => 'W3CSchool',
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 應(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 文件代碼如下:
實例
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 基礎(chǔ)類
以下提供了 RESTful 的一個基類,用于處理響應(yīng)請求的 HTTP 狀態(tài)碼,SimpleRest.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 文件代碼如下:
實例
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)擊以下按鈕下載:
更多建議: