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添加您自己的自定义错误处理逻辑。

  • 相关阅读:
    POJ 1469 COURSES 二分图最大匹配
    POJ 1325 Machine Schedule 二分图最大匹配
    USACO Humble Numbers DP?
    SGU 194 Reactor Cooling 带容量上下限制的网络流
    POJ 3084 Panic Room 求最小割
    ZOJ 2587 Unique Attack 判断最小割是否唯一
    Poj 1815 Friendship 枚举+求最小割
    POJ 3308 Paratroopers 最小点权覆盖 求最小割
    1227. Rally Championship
    Etaoin Shrdlu
  • 原文地址:https://www.cnblogs.com/victorlyw/p/10021081.html
Copyright © 2011-2022 走看看