• php 创建简单的Restful WebAPI(二)


      先说一下这个项目的代码结构吧。

      首先是index.php,我是把它作为中央控制器,一个调度器。程序通过rewrite或其他方式,把所有url导向本文件,由index.php调度其他代码。

      然后route.php,用设置好的路由规则匹配当前的url,来选择响应的controller(下面解释)来处理request,返回response。

      request.php,本文件用来解析requset信息(头部信息:method,accept,querystring,请求body的数据(主要为json格式)等),保存到内存里等待其他程序使用。

      response.php,本文件用来生成response信息(body数据(json格式),设置状态码,content-type等),返回给客户端。

      controller文件夹内的文件,这些文件用来处理具体业务逻辑,根据request.php,操作数据库,使用response.php生成结果返回给客户端。

      db.php由名字可知,本文件为数据库操作类(mysql)。

      还有其他类如日志功能,身份验证等等以后再实现吧。

      Rewite

      应用程序首先将所有url导向到index.php。可以使用Apache服务器mod_rewrite重写转向(Rewrite)模块来实现。由于我的web服务搭建在新浪SAE,它本身的config.yaml具有url重写功能,只需要加入一句 - rewrite: if(!is_file()) goto "index.php?%{QUERY_STRING}" 就可以了(config.yaml配置可参阅SAE相关文档)。

      Route

      首先在router.php配置相关规则:

    <?php
    /**
     *路由配置文件编写说明: 
     *  路由配置在一个array数组中,一条记录代表一个规则
     *  优先匹配索引低的规则
     *  key:   只接受2中规则 '/{controller}'和'/{controller}/{id}'。{controller}可用字符包括:字母,数字,_
     *  value: 第一项controller类名(文件名除去扩展名必须与类名相同);
     *         第二项id只能为正整数(包含0)
     *  controller文件必须位于'/controller'文件夹下;类名必须与文件名相同(除去扩展名.php),区分大小写。
    **/
    $routes= array(
        '/resources' => array('resources',''),
        '/resources/id' => array('resources','id'),
    );
    ?>

      routes数组保存应用程序的相关规则,由于时间紧迫,设置规则十分不灵活,后期需要加以修改,规则及其解析我们都可以随时进行调整。routes数组key为需要匹配的url,value为响应的controller名字。前文我们有提到,我们只需要处理2种url :'/resources' => array('resources','')表示匹配到/resources时,选择controller文件下的resources.php文件内的resources类来处理。'/resources/id' => array('resources','id'),大同小异,只不过我们需要,匹配并保存url中第二层的id。

      然后route.php解析上面的规则:

    <?php
    
    class Route
    {
        private $filepath;  
        private $classname;    
        private $id; 
        private $routepatterns; 
     
        public function __construct()
        {
            $this->filepath      = '';    
            $this->classname     = '';  
            $this->id            = null;
            $this->routepatterns = array(); 
            $this->initRoutes();
        }
    
        private function initRoutes()
        {
            $reg_m1 = '#^/(w+)$#';
            $reg_m2 = '#^/(w+)/id$#';
            $matches = array();
            $routes = array();
            include 'router.php';
            foreach($routes as $key=>$value){  
                
                if(preg_match($reg_m1,$key,$matches)){
                    $this->routepatterns[] = array('#^/('.$matches[1].')??$#i', array('controller/'.$value[0].'.php',$value[0]));
                }
                else if(preg_match($reg_m2,$key,$matches)){
                    $this->routepatterns[] = array('#^/('.$matches[1].')/(d+)??$#i', array('controller/'.$value[0].'.php',$value[0]));
                }
            }
        }
    
        public function processURL($urlpath)
        {
            $matches = array();
            foreach($this->routepatterns as $router){
                 if(preg_match($router[0],$urlpath,$matches)){
                     $filepath_ = '/'.$router[1][0];
                     $classname_ = $router[1][1];
                     $id_ = count($matches)>2?$matches[2]:null;
                     $this->setFilePath($filepath_);
                     $this->setClassName($classname_);
                     $this->setID($id_);
                     return true;
                 }
             }
             return false;
        }
    
        public function setFilePath($filepath)  
        {  
            $this->filepath = $filepath;  
        }  
      
        public function setClassName($classname)  
        {  
            $this->classname = $classname;  
        }  
      
        public function setID($id)  
        {  
            $this->id = $id;  
        }  
      
        public function getFilePath()  
        {  
            return $this->filepath;  
        }  
      
        public function getClassName()  
        {  
            return $this->classname;  
        }  
      
        public function getID()  
        {  
            return $this->id;  
        }  
      
    }
    
    ?>

       私有方法initRoutes(),是一个预处理方法。它解析了routes所有规则,保存routepatterns中,等待使用。processURL($urlpath)方法使用解析出的routepatterns匹配传入url,获取相应的结果,并记录下来。

      processURL($urlpath)方法是Rote类的核心,它将传入的url用之前定义的路由规则匹配。成功则获取controller,id(如果有),返回true;失败返回false。

  • 相关阅读:
    [计算机视觉]算法
    [python]python中**是什么
    ubuntu16.04增大swap空间
    conda查看某个安装包的依赖项
    conda install -c anaconda
    conda安装指定版本的指定包
    ValueError: Unable to determine SOCKS version from socks://127.0.0.1:1080/
    [ubuntu]卸载老版并安装最新版firefox
    使用anaconda创建tensorflow环境后如何在jupyter notebook中使用
    [python]numpy.mean()用法
  • 原文地址:https://www.cnblogs.com/coldlern/p/3948376.html
Copyright © 2020-2023  润新知