Latest web development tutorials

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 => 'w3big' ,
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 & #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 基礎類

以下提供了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 的站點w3big(本教程),訪問地址為http://localhost/restexample/site/list/3/,

源碼下載

實例中使用到的代碼可點擊以下按鈕下載:

源碼下載