2013-08-30 61 views
2

我正在努力獲取基本的RESTful API示例。目前我使用的例子是here,但它有一些錯誤並且不完整。使用PHP的基本RESTful API示例

我已經添加了以下行到我的.htaccess作爲示例所述。

<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule api/v1/(.*)$ api/v1/MyAPI.php?request=$1 [QSA,NC,L] 
</IfModule> 

然而,我的問題是簡單地得到我的具體類打印「12」。我不知道要訪問哪個URL,以便在屏幕上顯示消息「12」。

這裏是我的抽象類代碼:

<?php 
abstract class API 
{ 
    /** 
    * Property: method 
    * The HTTP method this request was made in, either GET, POST, PUT or DELETE 
    */ 
    protected $method = ''; 
    /** 
    * Property: endpoint 
    * The Model requested in the URI. eg: /files 
    */ 
    protected $endpoint = ''; 
    /** 
    * Property: verb 
    * An optional additional descriptor about the endpoint, used for things that can 
    * not be handled by the basic methods. eg: /files/process 
    */ 
    protected $verb = ''; 
    /** 
    * Property: args 
    * Any additional URI components after the endpoint and verb have been removed, in our 
    * case, an integer ID for the resource. eg: /<endpoint>/<verb>/<arg0>/<arg1> 
    * or /<endpoint>/<arg0> 
    */ 
    protected $args = Array(); 
    /** 
    * Property: file 
    * Stores the input of the PUT request 
    */ 
    protected $file = Null; 

    /** 
    * Constructor: __construct 
    * Allow for CORS, assemble and pre-process the data 
    */ 
    public function __construct($request) { 
     header("Access-Control-Allow-Orgin: *"); //any origin can be processed by this page 
     header("Access-Control-Allow-Methods: *"); //any HTTP method can be accepted 
     header("Content-Type: application/json"); 

     $this->args = explode('/', rtrim($request, '/')); 
     $this->endpoint = array_shift($this->args); 
     if (array_key_exists(0, $this->args) && !is_numeric($this->args[0])) { 
      $this->verb = array_shift($this->args); 
     } 

     $this->method = $_SERVER['REQUEST_METHOD']; 
     if ($this->method == 'POST' && array_key_exists('HTTP_X_HTTP_METHOD', $_SERVER)) { 
      if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'DELETE') { 
       $this->method = 'DELETE'; 
      } else if ($_SERVER['HTTP_X_HTTP_METHOD'] == 'PUT') { 
       $this->method = 'PUT'; 
      } else { 
       throw new Exception("Unexpected Header"); 
      } 
     } 

     switch($this->method) { 
     case 'DELETE': 
     case 'POST': 
      $this->request = $this->_cleanInputs($_POST); 
      break; 
     case 'GET': 
      $this->request = $this->_cleanInputs($_GET); 
      break; 
     case 'PUT': 
      $this->request = $this->_cleanInputs($_GET); 
      $this->file = file_get_contents("php://input"); 
      break; 
     default: 
      $this->_response('Invalid Method', 405); 
      break; 
     } 
    } 

    /** 
    * Determine if the concrete class implements a method for the endpoint that the client requested. If it does, then it calls that method, otherwise a 404 
    * response is returned 
    */ 
    public function processAPI() { 
     if ((int)method_exists($this->endpoint) > 0) { 
      return $this->_response($this->{$this->endpoint}($this->args)); 
     } 
     return $this->_response('', 400); 
    } 

    private function _response($data, $status = 200) { 
     header("HTTP/1.1 " . $status . " " . $this->_requestStatus($status)); 
     return json_encode($data); 
    } 

    private function _cleanInputs($data) { 
     $clean_input = Array(); 
     if (is_array($data)) { 
      foreach ($data as $k => $v) { 
       $clean_input[$k] = $this->_cleanInputs($v); 
      } 
     } else { 
      $clean_input = trim(strip_tags($data)); 
     } 
     return $clean_input; 
    } 

    private function _requestStatus($code) { 
     $status = 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 ($status[$code])?$status[$code]:$status[500]; 
    } 
} 

這裏是我的具體類的代碼(第8行麻煩):

<?php 
require_once 'API.php'; 
class MyAPI extends API 
{ 
    protected $User; 

    public function __construct($request, $origin) 
    { 
     echo "12"; 
     parent::__construct($request); 

     // Abstracted out for example 
     //$APIKey = new Models\APIKey(); 
     //$User = new Models\User(); 

     if (!array_key_exists('apiKey', $this->request)) { 
      throw new Exception('No API Key provided'); 
     } else if (!$APIKey->verifyKey($this->request['apiKey'], $origin)) { 
      throw new Exception('Invalid API Key'); 
     } else if (array_key_exists('token', $this->request) && !$User->get('token', $this->request['token'])){ 
      throw new Exception('Invalid User Token'); 
     } 

     //$this->User = $User; 
    } 

    /** 
    * Example of an Endpoint 
    */ 
    protected function example() 
    { 
     if ($this->method == 'GET') { 
      return "Your name is " . $this->User->name; 
     } else { 
      return "Only accepts GET requests"; 
     } 
    } 
} 

正如你可以看到8號線的具體類(在構造函數中)永遠不會被打印。我目前正試圖通過將讓我的工作,例如:

www.mysite.com/api/myAPI.php?request=get 

回答

2

在我看來這個URL是對REST原則

www.mysite.com/api/myAPI.php?request=get 

如果一個人在URL request=get然後使用目的HTTP提到GET死亡。
一個RESTful的URL應該是這樣的

www.mysite.com/api/myAPI.php 

和HTTP GET請求到該URL應該做的工作。

3

不知道你是否仍然需要這個答案,但我只是得到了我的工作,有一些調整。您的設置有幾個問題。首先是.htaccess文件。你有它指向MyAPI.php,但如果你閱讀教程,他實際上有第三個文件,api.php,實例化MyAPI類。行:

RewriteRule api/v1/(.*)$ api/v1/MyAPI.php?request=$1 [QSA,NC,L] 

應該是:

RewriteRule api/v1/(.*)$ api/v1/api.php?request=$1 [QSA,NC,L] 

你不應該試圖直接訪問MyAPI.php文件。相反,apache應指向api.php,並將請求細節傳遞給它。該api.php文件的內容(每平方釐米的部位)有:

<?php 
require_once 'MyAPI.php'; 
if (!array_key_exists('HTTP_ORIGIN', $_SERVER)) { 
    $_SERVER['HTTP_ORIGIN'] = $_SERVER['SERVER_NAME']; 
} 

try { 
    $API = new MyAPI($_REQUEST['request'], $_SERVER['HTTP_ORIGIN']); 
    echo $API->processAPI(); 
} catch (Exception $e) { 
    echo json_encode(Array('error' => $e->getMessage())); 
} 
?> 

的第二個問題是您的網址 - 你應該跟隨他的傳球端點(在他/我的情況,/ API/V1的例子/例)。這將生成MyAPI構造函數中的文本(如果您將其保留在您的文本中)以及來自示例端點函數的消息。對於它的價值,我將所有關鍵和用戶的東西都刪除了,以便我能夠運行它。所以我MyAPI.php文件看起來像:

<?php 
require_once 'AbstractAPI.php'; 
class MyAPI extends API 
{ 
    protected $testmessage; 
    public function __construct($request, $origin) { 
     parent::__construct($request); 
     $this->testmessage = "Test String"; 
    } 
    protected function example() 
    { 
     return $this->testmessage; 
    } 
} 
?> 

我採取了「開始簡單,後來打扮」的方法。祝你好運!