zoukankan      html  css  js  c++  java
  • 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添加您自己的自定义错误处理逻辑。

  • 相关阅读:
    权限设计
    ts infer关键字
    Array初始化 以及 Array.prototype.map()的一些问题
    同步、异步、事件循环
    Spring学习笔记(一)
    【面试】关于get和post两种方法的不同。
    【算法】背包问题
    当你在浏览器输入一个网址(如http://www.taobao.com),按回车之后发生了什么?
    数据库语句复习笔记
    【算法】雀魂启动(笔试题)
  • 原文地址:https://www.cnblogs.com/victorlyw/p/10021081.html
Copyright © 2011-2022 走看看