PHP框架开发——路由器功能

摘要:
路由器的实现大致分为一下几步1.将uri和控制器方法关联起来2.访问url时根据uri找到对应的绑定的控制器极其方法并执行其方法实现第一步我们模仿laravel中的那种方式使用Route::method;的方式来绑定,实现如下˂?in_array){thrownewException;}//判断传入的值是否合法if(count($arguments)!=2){thrownewException;}self::$get_coll[$arguments[0]][$name]=$arguments[1];}}这样可以将注册的路由按照数组的形式绑定好,方便我们按照uri和method快速查找出该url是否存在或者是否允许这种method方式访问router.php˂?

路由器的实现大致分为一下几步

1.将 uri 和 控制器方法关联起来

2.访问 url 时根据 uri 找到对应的绑定的控制器极其方法并执行其方法

实现第一步我们模仿 laravel 中的那种方式使用Route::method('uri','Controller@action');的方式来绑定,实现如下

<?php
classRouter
{
    private static $get_coll =[];

    public static function __callStatic($name, $arguments)
    {

        //判断方法是否正确
        if (!in_array(strtolower($name), ["post", "get", "put", "delete", "head"])) {
            throw new Exception("只支持 【post,get,put,delete,head】 请求");
        }

        //判断传入的值是否合法
        if (count($arguments) != 2) {
            throw new Exception("该方法需要输入两个参数,您输入了" . count($arguments) . "个");
        }

        self::$get_coll[$arguments[0]][$name] = $arguments[1];
    }
}

这样可以将注册的路由按照数组的形式绑定好,方便我们按照 uri 和 method 快速查找出 该url是否存在或者是否允许这种 method 方式访问

router.php

<?php
usevender
outerRouter;

Router::get("/message","MessageController@getMessage");
Router::post("/message","MessageController@getMessage");
Router::get("/test","MessageController@test");

存储数据结构如下

array(2) {
  ["/message"]=>
  array(2) {
    ["get"]=>
    string(28) "MessageController@getMessage"["post"]=>
    string(28) "MessageController@getMessage"}
  ["/test"]=>
  array(1) {
    ["get"]=>
    string(22) "MessageController@test"}
}

这样能够比较方便高效的获取到绑定的控制器和方法,并且判断该路由是否允许被某种方式(get/post等)访问

public static function getRoute($uri, $method)
    {
        $method = strtolower($method);
        if (isset(self::$get_coll[$uri])) {
            //判断方法是否一致
            if (isset(self::$get_coll[$uri][$method])) {
                return self::$get_coll[$uri][$method];
            } else{
                throw new Exception("method not allow");
            }
        } else{
            throw new Exception("404 not fond");
        }
    }

第二步,当获取到路由绑定的控制器和方法时,应该执行相应的控制器和方法获取执行结果,这里我是用的是反射的方式

list($controller,$action) = explode("@",$controller);
//使用反射实例化类
$ref = new ReflectionClass("app\Http\Controller\".$controller);
$controller_instance = $ref->newInstance();
call_user_func_array([$controller_instance,$action],[$request,$response]);

还有一种方式效率应该更高

$controller = "app\Http\Controller\".$controller;
(new $controller)->$action($request,$response);

到这里有个简单的路由功能就实现啦,当然还有很多可以优化的空间

代码示例:https://github.com/gphper/MySwoole

免责声明:文章转载自《PHP框架开发——路由器功能》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇H3Cj交换机重启WPF中RadioButton绑定数据的正确方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[GXYCTF2019]BabysqliV3.0题解

[GXYCTF2019]BabysqliV3.0 常规分析 题目叫babysqli,刚访问的时候会有一个登录页面,于是我用测了测sql注入,毫无收获。 最后发现是弱口令,账号admin,密码password。 登录进去以后是这样的: url末尾是file=的形式,怀疑是文件包含,并且自动在xxx后面加.php。 将file=后面的参数改为php://fi...

如何在PHP5中通过PDO连接SQLite3数据库

  通过PHP跟PDO配置SQLite数据库是一件很繁琐的事情,经过一下午的研究,终于理清了里面的思路。现在拿出来跟大家共享。初学,错误请指出。 首先我们先选择要使用的web server 软件,由于从兼容性跟性能方面的需求,我选择了目前来说最新版的apache。 第二步,我们要使用目前最新版本的PHP zip package .这里提示大家一下,经过我痛...

PHP5和PHP7引用对比(笔记)

php5在引入引用计数后,使用了refcount_gc来记录次数,同时使用is_ref_gc来记录是否是引用类型。 例如 $a = 'hello'; //$a->zval1(type=IS_STRING,refcount_gc=1,is_ref_gc=0) 这个时候$a指向一个结构体,主要看refcount_gc=1,这就是引用计数字段,因为hell...

Mac安装PHP运行环境

先安装brew ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" nginx的安装与配置 brew install nginx 修改配置文件 sudo vim /usr/local/etc/nginx/nginx.conf #修...

关于任意文件下载及上传漏洞

目录 任意文件读取下载 1、原理 2、利用方式 3、漏洞修复 4、实例 任意文件上传 1、原理 2、分类 3、基本思路 4、基本绕过方式 1、客户端检测绕过(javascript 检测) 2、服务端验证绕过(MIME 类型检测) 3、代码注入绕过--getimagesize() 4、路径/扩展名绕过 5、安全防范 6、图片二次渲染 7、...

宝塔面板-切换默认的php版本

方法一:   对于线上服务器部署,对于我们一些非专业运维程序员来说,『宝塔』镜像提供的服务器管理软件,给我们提供了极大的遍历。所以,新服务器的系统,打算直接采用宝塔镜像。       因不同系统,我们可能需要不同的 PHP 版本,宝塔支持安装多个 PHP 版本,并且,允许不同项目配置不同的 PHP 版本。       但当我们想在 li...