PHP 轻量级 REST框架

Posted victorlyw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP 轻量级 REST框架相关的知识,希望对你有一定的参考价值。

GITHUB:https://github.com/jacwright/RestServer

简介:

一个php REST服务器,用于提供非常轻量级的REST API。很容易上手。独立于其他库和框架。支持HTTP身份验证。

参考Zend Framework,该框架省略了Zend Framework MVC附带的大量类。还有一些有用的功能要添加(例如XML支持)。

RestServer到目前为止,该框架的解决方案是一个JSON REST服务器。添加对XML或其他格式的支持应该是微不足道的,但是必须假设您的对象在XML中的样子(XML-RPC样式,您自己的自定义XML格式等)。

首先,我们将查看您编写的用于处理请求的类,然后我们将查看如何在index.php文件中将它们绑定在一起。

使用教程:

从URL到类方法获取请求的映射都在类的doc-comments中。以下是处理某些用户操作的类的示例:

<?php

use JacwrightRestServerRestException;

class TestController
{
    /**
     * Returns a JSON string object to the browser when hitting the root of the domain
     *
     * @url GET /
     */
    public function test()
    {
        return "Hello World";
    }

    /**
     * Logs in a user with the given username and password POSTed. Though true
     * REST doesn‘t believe in sessions, it is often desirable for an AJAX server.
     *
     * @url POST /login
     */
    public function login()
    {
        $username = $_POST[‘username‘];
        $password = $_POST[‘password‘]; //@todo remove since it is not needed anywhere
        return array("success" => "Logged in " . $username);
    }

    /**
     * Gets the user by id or current user
     *
     * @url GET /users/$id
     * @url GET /users/current
     */
    public function getUser($id = null)
    {
        // if ($id) {
        //     $user = User::load($id); // possible user loading method
        // } else {
        //     $user = $_SESSION[‘user‘];
        // }

        return array("id" => $id, "name" => null); // serializes object into JSON
    }

    /**
     * Saves a user to the database
     *
     * @url POST /users
     * @url PUT /users/$id
     */
    public function saveUser($id = null, $data)
    {
        // ... validate $data properties such as $data->username, $data->firstName, etc.
        // $data->id = $id;
        // $user = User::saveUser($data); // saving the user to the database
        $user = array("id" => $id, "name" => null);
        return $user; // returning the updated or newly created user object
    }

    /**
     * Gets user list
     *
     * @url GET /users
     */
    public function listUsers($query)
    {
        $users = array(‘Andra Combes‘, ‘Valerie Shirkey‘, ‘Manda Douse‘, ‘Nobuko Fisch‘, ‘Roger Hevey‘);
        if (isset($query[‘search‘])) {
          $users = preg_grep("/{$query[search]}/i", $users);
        }
        return $users; // serializes object into JSON
    }

    /**
     * Get Charts
     * 
     * @url GET /charts
     * @url GET /charts/$id
     * @url GET /charts/$id/$date
     * @url GET /charts/$id/$date/$interval/
     * @url GET /charts/$id/$date/$interval/$interval_months
     */
    public function getCharts($id=null, $date=null, $interval = 30, $interval_months = 12)
    {
        echo "$id, $date, $interval, $interval_months";
    }

    /**
     * Throws an error
     * 
     * @url GET /error
     */
    public function throwError() {
        throw new RestException(401, "Empty password not allowed");
    }
}

让我们通过上面的TestController课程来讨论所展示的功能。首先我们来看看这个test方法。您会注意到docblock中有一种新的doc-comment标记。@url将URL映射到它下面的方法,格式如下:

@url <REQUEST_METHOD> <URL>

在这个特定的例子中,当某人在http://www.example.com/上进行GET时(假设example.com是我们的服务所在的位置),它将打印出来:

"Hello World"

这是JSON中字符串的有效表示。

继续下一个方法,login我们看到@url将任何POST映射到http://www.example.com/login到该login方法。从常规Web类型的POST获取数据与任何PHP应用程序相同,允许您将自己的验证或其他框架与此REST服务器结合使用。如果需要,也可以保留会话。虽然保持会话不是真正的REST风格,但我们通常只需要一个REST服务器来为我们的ajax应用程序提供数据,并且使用会话比使用RESTful更容易。

接下来我们有了我们的getUser方法(你会注意到我命名我的方法并不重要,因为我们的@url指令定义了哪些URL映射到方法)。你可以在这里看到几件事。首先,我们@url为此方法提供了多个映射。第二,/$id第一个URL映射有一个奇怪的地方RestServer将任何:keyword占位符视为URL中的通配符,并将获取URL的该部分并将其传递给方法中具有相同名称的参数。在此示例中,当访问http://www.example.com/users/1234时$id将等于1234.当访问http://www.example.com/users/current时$id将等于null。您的参数的顺序无关紧要,只要它们与占位符(:id$id:username$username具有相同的名称即可$id = null当您有多个不需要参数的URL映射时,您还需要确保将参数设置为optional()。否则,您将抛出一个错误,告诉您没有传入必需的参数。

最后要注意的getUser是,此方法只返回一个User对象。这会被序列化为JSON(或可能是XML)并打印出来供应用程序使用。

接下来我们必须saveUser你在这里看到我们再次有多个URL映射。这次他们还有不同的HTTP方法(POST和PUT)来创建和更新用户。这里的新东西是$data变量。这是一个特殊的关键字参数,它将包含POSTed或PUT到服务器的值。这与常规Web POST不同,它不需要只是名称 - 值对,但可以像JSON一样,发送复杂对象。例如,常规Web POST的主体,比如登录请求,可能如下所示:

username=bob&password=supersecretpassw0rd

但为我们的saveUser方法发布一个新的用户对象可能如下所示

{ “ username ”:“ bob ”,“ password ”:“ supersecretpassword ”,“ firstName ”:“ Bob ”,“ lastName ”:“ Smith ” }

因此,除了常规的Web样式POST之外,您还可以允许POSTING JSON。

最后我们得到listUsers方法。test方法简单$query参数是新的。此特殊参数可用于读取查询字符串。并将查询字符串参数保存为关联数组。例如,如果客户端使用url请求此API,/users?search=Manda$query参数将保持[search => Manada]

我称这些类来处理请求Controllers并且它们可以通过URL映射,数据库配置等完全自包含,这样您就可以毫不费力地将它们放入其他RestServer服务中。

REST index.php

为了让整个服务器启动,你需要创建一个index.php文件,让你的URL重写直接请求(另一个你可以在其他地方学到的主题),然后创建RestServer并添加控制器类到它用于处理。RestServer将使用APC或文件缓存请求之间的URL映射以加速请求。如果使用自动加载和此缓存,则不必在每个请求上加载每个控制器文件,只需要请求所需的文件。缓存仅在生产模式下运行。这是一个示例index.php文件:

spl_autoload_register(); //除非我们使用它们,否则不要加载我们的类

$ mode  =  ‘ debug ‘ ; // ‘debug‘或‘production‘ 
$ server  =  new  RestServer($ mode); 
// $ server-> refreshCache(); //如果类在生产模式下更改,则暂时取消注释以清除缓存

$ server - > addClass(‘ TestController ‘); 
$ server - > addClass(‘ ProductsController ‘,‘ / products ‘); //将此添加为此类中所有URL的基础

$ server - > handle();

而已。您可以根据需要添加任意数量的类。如果存在冲突,则稍后添加的类将覆盖先前添加的重复URL映射。addClass中的第二个参数可以是一个基本URL,它将作为给定类中URL映射的前缀,使您可以更加模块化。

您可以查看RestServer类,复制它并将其用于您自己的目的。它是在MIT许可下。要添加的功能包括XML支持和HTTP身份验证支持。如果您更好地完成此课程,请通过发表评论与大家分享您的更新。我将尝试使用新功能更新此类,因为它们是共享的。我希望你喜欢!

祝你好运,如果你最终使用它,请告诉我!

更新:我为可能需要它的人提供了一个示例.htaccess文件。它只会重写对不存在的文件的请求,因此您可以在webroot中拥有images,css或其他PHP文件,它们仍然有效。任何能给404的东西都会重定向到你的index.php文件。

DirectoryIndex index.php
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteRule ^$ index.php [QSA,L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

认证

身份验证对每个应用程序都是唯 但是将身份验证机制绑定到RestServer很容易。只需添加一个名为所有请求的方法authorizeController就会先调用该方法。如果authorize()返回false,则服务器将发出401 Unauthorized响应。如果authorize()返回true,则请求继续调用正确的控制器操作。除非您添加@noAuth操作的文档(我通常将其置于@url映射之上),否则所有操作都将首先运行授权

在您的身份验证方法中,您可以使用PHP的getallheaders功能或$_COOKIE根据您的用户授权方式。这是您从数据库加载用户对象的位置,并将其设置为$this->user = getUserFromDatabase()以便在以后调用时您的操作可以访问它。

RestServer是一种将应用程序映射到REST API的简单机制。其余细节由您决定。

跨域资源共享

出于安全原因,浏览器限制从脚本内发起的跨源HTTP或REST请求。因此,使用来自浏览器的REST API的Web应用程序只能向其自己的域发出API请求。RestServer通过在REST index.php文件中包含以下代码,可以将覆盖此限制配置为允许交叉请求请求。

/*
 * 在$ server = new RestServer($ mode)之后包含以下行; 
 * 或使用阵列中的多个起点的$服务器- > allowedOrigin = 阵列( ‘ http://example.com ‘, ‘ https://example.com ‘); 
 * 或通配符$ server - > allowedOrigin = ‘ * ‘  
*/
 $ server - > useCors = true ; $ server - > allowedOrigin = ‘ http://example.com ‘ ;    

异常抛出错误处理

您可以通过在类中抛出一个例外来轻松地向API用户提供错误RestException

/ **
  * 按id或当前用户获取用户
  * 
  * @url GET / users / $ id 
  * @url GET / users / current 
* / 
public function getUser( $ id = null) { 
    if( $ id){ 
        $ user = User :: load( $ id); //可能的用户加载方法     
        if(!$ user){ 
            throw new RestException(404,‘ User not found ‘);             
        }                  
    } else { 
        $ user = $ _SESSION [ ‘ user ‘ ];         
    }              
    return  $ user ; //将对象序列化为JSON
};

您可以控制REST服务处理错误的方式。您可以使用添加错误控制器$server->addErrorClass(‘ErrorController‘);

此控制器可以定义命名的方法handle401handle404添加您自己的自定义错误处理逻辑。

以上是关于PHP 轻量级 REST框架的主要内容,如果未能解决你的问题,请参考以下文章

Django rest_framewok框架的基本组件

java都有哪些好用的REST框架

php手撸轻量级开发框架加载

Symfony 的独立 PHP 项目使用哪个 MongoDB 库?

Symfony 的独立 PHP 项目使用哪个 MongoDB 库?

Restlet 简介