2017-02-18 3 views
0

PHP에서 적절한 RESTful API를 만들기 위해 노력하고 있습니다. 나는 에서 몇 가지 단계를 수행해 왔으며 시도한 결과를 제외하고는 정확히 동일한 것을 모두 수행 한 것처럼 보입니다. http://localhost/api/v1/example 내부 서버 오류가 발생합니다. 아파치 오류 로그에서PHP에서 리디렉션 오류가 발생하는 휴식 API 만들기

나는 다음과 같은보고 있어요 :

[Sat Feb 18 19:30:10.594193 2017] [core:error] [pid 10272:tid 1144] [client ::1:58203] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace. 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3747): [client ::1:58203] AH00121: r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/api.php 
[Sat Feb 18 19:30:10.594193 2017] [core:debug] [pid 10272:tid 1144] core.c(3753): [client ::1:58203] AH00122: redirected from r->uri = /api/v1/example 

내 BaseAPI 클래스 것은 (그들이 예에서 API 부르는) 다음과 같습니다 : 다음과 같이

abstract class API 
{ 
    protected $method = ''; 
    protected $endpoint = ''; 
    protected $verb = ''; 
    protected $args = Array(); 

    public function __construct($request) 
    { 
     header("Access-Control-Allow-Origin: *"); 
     header("Access-Control-Allow-Method: *"); 
     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->clearInputs($_GET); 
       $this->file = file_get_contents("php://input"); 
       break; 
      default: 
       $this->response('Invalid Method', 405); 
       break; 
     } 
    } 

    public function processAPI() 
    { 
     if (method_exists($this, $this->endpoint)) 
     { 
      return $this->response($this->{$this->endpoint}($this->args)); 
     } 
     return $this->response("No Endpoint: $this->endpoint", 404); 
    } 

    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 $key => $value) 
      { 
       $clean_input[$key] = $this->cleanInputs($value); 
      } 
     } 
     else 
     { 
      $clean_input = htmlspecialchars($data); 
     } 
     return $clean_input; 
    } 

    private function requestStatus($code) 
    { 
     $status = array(
      200 => 'OK', 
      404 => 'Not Found', 
      405 => 'Method Not Allowed', 
      500 => 'Internal Server Error' 
     ); 
     return ($status[$code])?$status[$code]:$status[500]; 
    } 
} 

MyAPI 파일이 다음과 같이

require_once 'BaseApi.php'; 

class MyAPI extends API 
{ 
    public function __construct($request) 
    { 
     parent::__construct($request); 
    } 

    protected function example() 
    { 
     if ($this->method === "GET") 
     { 
      return "Hello to my RESTful API"; 
     } 
     else 
     { 
      return "Only accepts GET requests"; 
     } 
    } 
} 

내 api.php은 다음과 같습니다

다음과 같이 0
require_once 'MyAPI.php'; 

try 
{ 
    $api = new MyAPI($_REQUEST['request']); 
    echo $api->processAPI(); 
} 
catch (Exception $ex) 
{ 
    echo $ex->getMessage(); 
} 

내 htaccess로 파일은 다음과 같습니다 모두가 어떤 차이가 만약 내가 Windows에서 실행 WAMP 서버를 사용하고, 정확하게 그 기사에서와 동일 나에게 같은

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

같습니다 10.

도움을 주셔서 감사합니다.

+0

MVC를 만들려고 할 때 Slim PHP MVC를 사용합니다. 나는 튜토리얼을 보았고 그것은 다소 복잡해 보였다. 어쩌면 슬림 한가? https://www.slimframework.com/ –

답변

1

동일한 기본 디렉토리에 모든 파일 .htaccess*.php이 있습니다.

이 경우 대체 파일 은 존재하지 않는 파일에 대한 또 다른 요청으로 간주됩니다. api.php이 현재 디렉토리에 있고 api/v1이 아니기 때문입니다.

따라서 api/v1/example

등등 api/v1/api.php?request=example 재기록하고 api/v1/api.php?request=api.php 재기록하고 api/v1/api.php?request=api.php 재기록 될 것이다.

당신이 하위 디렉토리 api/v1의 기본 디렉토리 및 모든 PHP 파일의 .htaccess이 있어야합니다,이 일을합니다. 당신은 하나의 디렉토리에있는 파일을 유지하려면 다시 쓰기 규칙의 대상은 기존 스크립트 파일 api.php?request=$1, 예를 들어,에


지정해야

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule api/v1/(.*)$ api.php?request=$1 [QSA,NC,L] 
+0

아, 그게 의미가 있습니다, 나는 그것을 시도하고 그것을 작동합니다. 당신의 도움을 주셔서 감사합니다 – Boardy

관련 문제