PHP 實現(xiàn) RESTful 風格的 API

PHP實現(xiàn) RESTful 風格的 API

目錄詳情

restful/
    - Request.php 數(shù)據(jù)操作類
    - Response.php 輸出類
    - index.php 入口文件
    - .htaccess 重寫url

Request.php

  • 包含一個Request類旦签,即數(shù)據(jù)操作類缺猛。

  • 接收到URL的數(shù)據(jù)后儡司,根據(jù)請求URL的方式(GET|POST|PUT|PATCH|DELETE)對數(shù)據(jù)進行相應的增刪改查操作限匣,并返回操作后的結(jié)果

      <?php
      /**
      * Request類,
      * 接收到URL的數(shù)據(jù)后彤守,根據(jù)請求URL的方式(GET|POST|PUT|PATCH|DELETE)對數(shù)據(jù)進行相應的增刪改查操作徙融,并返回操作后的結(jié)果
      */
      class Request
      {
          // 允許的請求方式
          private static $method_type = array('get', 'post', 'put', 'patch', 'delete');
    
          // 測試數(shù)據(jù)
          private static $test_class = array(
              1 => array('name'=>'測試一班','count'=>18), 
              2 => array('name'=>'測試二班','count'=>15)
          );
    
          public static function getRequest()
          {
              // 請求方法
              $method = strtolower($_SERVER['REQUEST_METHOD']);
              if (in_array($method, self::$method_type)) {
                  // 調(diào)用請求方法對應的方法
                  $data_name = $method . "Data";
                  return self::$data_name($_REQUEST);
              }
              return false;
          }
    
          // GET 獲取信息
          private static function getData($request_data)
          {
              $class_id = (int)$request_data['class'];
              if ($class_id > 0) {
                  // GET /class/ID: 獲取某個指定班的信息
                  return self::$test_class[$class_id];
              }else{ 
                  // GET /class: 列出所有班級
                  return self::$test_class;
              }
          }
    
          // POST /class 新建一個班級
          private static function postData($request_data)
          {
              $class_id = (int)$request_data['class'];
              if ($class_id == 0) {
                  return false;
              }
              $data = array();
              if (!empty($request_data['name']) && isset($request_data['count'])) {
                  $data['name'] = $request_data['name'];
                  $data['count'] = $request_data['count'];
                  self::$test_class[] = $data;
                  return self::$test_class; 
              }else{
                  return false;
              }
          }
    
          // PUT /class/ID 更新某個指定班級的信息(全部信息)
          private static function putData($request_data)
          {
              $class_id = (int)$request_data['class'];
              if ($class_id == 0) {
                  return false;
              }
    
              $data = array();
              if (!empty($request_data['name']) && isset($request_data['count'])) {
                  $data['name'] = $request_data['name'];
                  $data['count'] = (int)$request_data['count'];
                  self::$test_class[$class_id] = $data;
                  return self::$test_class;
              }else{
                  return false;
              }
          }
    
          // PATCH /class/ID 更新某個指定班級的信息 (部分信息)
          private static function pacthData($request_data)
          {
              $class_id = (int)$request_data['class'];
              if ($class_id == 0) {
                  return false;
              }
              if (!empty($request_data['name'])) {
                  self::$test_class[$class_id]['name'] = $request_data['name'];
              }
              if (isset($request_data['count'])) {
                  self::$test_class[$class_id]['count'] = $request_data['count'];
              }
              return self::$test_class;
          }
    
          // DELETE /class/ID 刪除某個班
          private static function deleteData($request_data)
          {
              $class_id = (int)$request_data['class'];
              if ($class_id == 0) {
                  return false;
              }
              unset(self::$test_class[$class_id]);
              return self::$test_class;
          }
      }
      ?>
    

Response.php

  • 包含一個Response類洒缀,即輸出類。

  • 根據(jù)接收到的Content-Type欺冀,將Request類返回的數(shù)組拼接成對應的格式树绩,加上header后輸出

      <?php
      /**
      * 包含一個Response類,即輸出類隐轩。根據(jù)接收到的Content-Type饺饭,將Request類返回的數(shù)組拼接成對應的格式,加上header后輸出
      */
      class Response
      {
          const HTTP_VERSION = "HTTP/1.1";
      
          public function sendResponse($data)
          {
              // 獲取數(shù)據(jù)
              if ($data) {
                  $code = 200;
                  $message = "OK";
              }else{
                  $code = 404;
                  $data = array('error' => "Not Found");
                  $message = "Not Found";
              }
      
              header(self::HTTP_VERSION . " $code $message");
              $content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : $_SERVER['HTTP_ACCEPT'];
              if (strpos($content_type, 'application/json') !== false) {
                  header("Content-Type: application/json");
                  echo self::encodeJson($data);
              }elseif (strpos($content_type, 'application/xml') !== false) {
                  header("Content-Type: application/xml");
                  echo self::encodeXml($data);
              }else{
                  header("Content-Type: text/html");
                  echo self::encodeHtml($data);
              }
          }
      
          // json 格式
          private static function encodeJson($responseData)
          {
              return json_encode($responseData);
          }
      
          // xml 格式
          private static function encodeXml($responseData)
          {
              $xml = new SimpleXMLElement('<?xml version="1.0"?><rest></rest>');
              foreach ($responseData as $key => $value) {
                  if (is_array($value)) {
                      foreach ($value as $k => $v) {
                          $xml->addChild($k,$v);
                      }
                  }else{
                      $xml->addChild($key,$value);
                  }
              }
              return $xml->asXML();
          }
      
          // html 格式
          private static function encodeHtml($responseData)
          {
              $html = "<table border='1'>";
              foreach ($responseData as $key => $value) {
                  $html .= "<tr>";
                  if (is_array($value)) {
                      foreach ($value as $k => $v) {
                          $html .= "<td>$k</td><td>$v</td>";
                      }
                  }else{
                      $html .= "<td>$key</td><td>$value</td>";
                  }
                  $html .= "</tr>";
              }
              $html .="</table>";
              return $html;
          }
      }
      ?>
    

index.php

  • 入口文件
  • 調(diào)用 Request->getRequest 獲取數(shù)據(jù)
  • 調(diào)用 Response->sendResponse 處理并返回數(shù)據(jù)

.htaccess

  • 重寫URL职车,使URL以 /restful/class/1 形式訪問文件

      Options +FollowSymlinks
      RewriteEngine on
      
      # 重寫規(guī)則
      RewriteRule ^class$   index.php?class=all [nc,qsa]
      RewriteRule ^class/(\d+)$   index.php?class=$1 [nc,qsa]
    

測試方法

  • 采用 postman 測試

GET

  • 獲取 json 類型
    • image
  • 獲取 xml
    • image
  • 獲取 html
    • image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘫俊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子悴灵,更是在濱河造成了極大的恐慌扛芽,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件积瞒,死亡現(xiàn)場離奇詭異川尖,居然都是意外死亡,警方通過查閱死者的電腦和手機茫孔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門叮喳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缰贝,你說我怎么就攤上這事馍悟。” “怎么了剩晴?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵锣咒,是天一觀的道長。 經(jīng)常有香客問我李破,道長宠哄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任嗤攻,我火速辦了婚禮毛嫉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妇菱。我一直安慰自己承粤,他們只是感情好暴区,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辛臊,像睡著了一般仙粱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彻舰,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天伐割,我揣著相機與錄音,去河邊找鬼刃唤。 笑死隔心,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的尚胞。 我是一名探鬼主播硬霍,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼党涕,長吁一口氣:“原來是場噩夢啊……” “哼姐仅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莽鸿,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤躬柬,失蹤者是張志新(化名)和其女友劉穎拜轨,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楔脯,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡撩轰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昧廷。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡偎箫,死狀恐怖木柬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淹办,我是刑警寧澤眉枕,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站怜森,受9級特大地震影響速挑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜副硅,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一姥宝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恐疲,春花似錦腊满、人聲如沸套么。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胚泌。三九已至,卻和暖如春肃弟,著一層夾襖步出監(jiān)牢的瞬間玷室,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工笤受, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阵苇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓感论,卻偏偏與公主長得像绅项,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子比肄,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容