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
Class Site {
    
    private $sites = array(
        1 => &qpos;TaoBao&qpos;,  
        2 => &qpos;Google&qpos;,  
        3 => &qpos;Runoob&qpos;,              
        4 => &qpos;Baidu&qpos;,              
        5 => &qpos;Weibo&qpos;,  
        6 => &qpos;Sina&qpos;
            
    );
        
    
    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 文件中,我们通过设置参数 &qpos;view&qpos; 来获取 RestController.php 文件中对应的请求,通过获取 &qpos;view&qpos; 不同的参数来分发到不同的方法上。RestController.php 文件代码如下:
 
实例
 
<?php
require_once("SiteRestHandler.php");
        
$view = "";
if(isset($_GET["view"]))
    $view = $_GET["view"];
switch($view){
 
    case "all":
        
        $siteRestHandler = new SiteRestHandler();
        $siteRestHandler->getAllSites();
        break;
        
    case "single":
        
        $siteRestHandler = new SiteRestHandler();
        $siteRestHandler->getSite($_GET["id"]);
        break;
 
    case "" :
        
        break;
}
?>
  
简单的 RESTful 基础类
以下提供了 RESTful 的一个基类,用于处理响应请求的 HTTP 状态码,SimpleRest.php 文件代码如下:
 
实例
 
<?php 
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 => &qpos;Continue&qpos;,  
            101 => &qpos;Switching Protocols&qpos;,  
            200 => &qpos;OK&qpos;,
            201 => &qpos;Created&qpos;,  
            202 => &qpos;Accepted&qpos;,  
            203 => &qpos;Non-Authoritative Information&qpos;,  
            204 => &qpos;No Content&qpos;,  
            205 => &qpos;Reset Content&qpos;,  
            206 => &qpos;Partial Content&qpos;,  
            300 => &qpos;Multiple Choices&qpos;,  
            301 => &qpos;Moved Permanently&qpos;,  
            302 => &qpos;Found&qpos;,  
            303 => &qpos;See Other&qpos;,  
            304 => &qpos;Not Modified&qpos;,  
            305 => &qpos;Use Proxy&qpos;,  
            306 => &qpos;(Unused)&qpos;,  
            307 => &qpos;Temporary Redirect&qpos;,  
            400 => &qpos;Bad Request&qpos;,  
            401 => &qpos;Unauthorized&qpos;,  
            402 => &qpos;Payment Required&qpos;,  
            403 => &qpos;Forbidden&qpos;,  
            404 => &qpos;Not Found&qpos;,  
            405 => &qpos;Method Not Allowed&qpos;,  
            406 => &qpos;Not Acceptable&qpos;,  
            407 => &qpos;Proxy Authentication Required&qpos;,  
            408 => &qpos;Request Timeout&qpos;,  
            409 => &qpos;Conflict&qpos;,  
            410 => &qpos;Gone&qpos;,  
            411 => &qpos;Length Required&qpos;,  
            412 => &qpos;Precondition Failed&qpos;,  
            413 => &qpos;Request Entity Too Large&qpos;,  
            414 => &qpos;Request-URI Too Long&qpos;,  
            415 => &qpos;Unsupported Media Type&qpos;,  
            416 => &qpos;Requested Range Not Satisfiable&qpos;,  
            417 => &qpos;Expectation Failed&qpos;,  
            500 => &qpos;Internal Server Error&qpos;,  
            501 => &qpos;Not Implemented&qpos;,  
            502 => &qpos;Bad Gateway&qpos;,  
            503 => &qpos;Service Unavailable&qpos;,  
            504 => &qpos;Gateway Timeout&qpos;,  
            505 => &qpos;HTTP Version Not Supported&qpos;);
        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(&qpos;error&qpos; => &qpos;No sites found!&qpos;);        
        } else {
            $statusCode = 200;
        }
 
        $requestContentType = $_SERVER[&qpos;HTTP_ACCEPT&qpos;];
        $this ->setHttpHeaders($requestContentType, $statusCode);
                
        if(strpos($requestContentType,&qpos;application/json&qpos;) !== false){
            $response = $this->encodeJson($rawData);
            echo $response;
        } else if(strpos($requestContentType,&qpos;text/html&qpos;) !== false){
            $response = $this->encodeHtml($rawData);
            echo $response;
        } else if(strpos($requestContentType,&qpos;application/xml&qpos;) !== false){
            $response = $this->encodeXml($rawData);
            echo $response;
        }
    }
    
    public function encodeHtml($responseData) {
    
        $htmlResponse = "<table border=&qpos;1&qpos;>";
        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) {
        
        $xml = new SimpleXMLElement(&qpos;<?xml version="1.0"?><site></site>&qpos;);
        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(&qpos;error&qpos; => &qpos;No sites found!&qpos;);        
        } else {
            $statusCode = 200;
        }
 
        $requestContentType = $_SERVER[&qpos;HTTP_ACCEPT&qpos;];
        $this ->setHttpHeaders($requestContentType, $statusCode);
                
        if(strpos($requestContentType,&qpos;application/json&qpos;) !== false){
            $response = $this->encodeJson($rawData);
            echo $response;
        } else if(strpos($requestContentType,&qpos;text/html&qpos;) !== false){
            $response = $this->encodeHtml($rawData);
            echo $response;
        } else if(strpos($requestContentType,&qpos;application/xml&qpos;) !== 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 的站点 Runoob(菜鸟教程),访问地址为 http://localhost/restexample/site/list/3/,

源码下载
实例中使用到的代码可点击以下按钮下载:
源码下载