簡體   English   中英

在PHP中創建Rest API導致重定向錯誤

[英]Creating a Rest API in PHP causing a redirect error

我正在嘗試在PHP中創建適當的RESTful API。 我一直在遵循http://coreymaynard.com/blog/creating-a-restful-api-with-php/中的一些步驟,對我來說,除了我嘗試去時,我似乎做的所有事情都完全一樣到http:// localhost / api / v1 / example我收到內部服務器錯誤。

在apache錯誤日志中,我看到以下內容:

[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如下:

require_once 'MyAPI.php';

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

我的.htaccess文件如下:

<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>

在我看來,一切都與該文章中的內容完全相同,如果有什么不同,我使用的是在Windows 10上運行的Wamp服務器。

我懷疑,所有文件.htaccess*.php位於同一基本目錄中。

在這種情況下,替換api/v1/api.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等。


要使其工作,必須在基本目錄中具有.htaccess ,並且在子目錄api/v1必須具有所有PHP文件。


如果要將文件保留在一個目錄中,則重寫規則的目標必須指向現有的腳本文件api.php?request=$1 ,例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM