美文网首页
手写一个laravel(七) 路由实现

手写一个laravel(七) 路由实现

作者: mafa1993 | 来源:发表于2020-12-03 20:24 被阅读0次

    手写一个laravel(七) 路由实现

    1. 创建Route/Router.php 为路由的实现类,实现get,any等方法
    2. 在Application的registerCoreContainerAliases中进行绑定
    3. 在Support的Facades下创建Route.php,将路由类可以使用门面加载
    4. 在RouteServicePrivoder的boot方法中调用register,传递路由路径
    5. 路由匹配 index.php->Kernel.php->haandle()->Router.php->dispatcher()->find()->match()
    6. 路由执行,如果是一个控制器,需要设置控制器的命名空间,在Route的服务提供者中进行设定,这样可以方便的修改命名空间,而不需要对Route类去进行修改

    源码见个人git https://github.com/mafa1993/slaravel

    <?php
    
    namespace Slaravel\Route;
    
    use Slaravel\Foundation\Application;
    
    class Router
    {
        protected $routes = [];
        protected $verbs = ['GET','POST','PUT'];
        protected $action;
        protected $namespace;
        protected $controller;
        protected $app;
    
        public function __construct(Application $app)
        {
            //用于app的注入
            $this->app = $app;
        }
    
        public function get($uri,$action){
            $this->addRoute(['GET'],$uri,$action);
        }
    
        public function any($uri,$action){
            $this->addRoute($this->verbs,$uri,$action);
        }
    
    
        /**
         * @param array $method any会传递多个
         * @param $uri
         * @param $action
         */
        protected function addRoute($method,$uri,$action){
            foreach ($method as $v){
                $this->routes[$v][$uri] = $action;
            }
        }
    
        public function getRoutes(){
            var_dump('get Route');
            return $this->routes;
        }
    
        /**
         * 获取路由文件路径
         * @param $route_path
         */
        public function register($route_path){
            //因为门面传参是[...$arguments]
            echo 'router register   ';
            require_once("$route_path");
        }
    
        /**
         * 对路由进行匹配执行
         * @param $request
         */
        public function dispatcher($request){
            //匹配路由
            $this->findRoute($request);
            //执行路由
            $this->runRoute($request);
        }
    
        /**
         * 查找路由
         * @param $request
         */
        public function findRoute($request){
            //路由查找 请求方式和uri
            $this->match($request->getMethod(),$request->getUri());
    
        }
    
        /**
         * 获取匹配的路由规则
         */
        protected function match($method,$path){
            $routes = $this->routes;
            foreach ($routes[$method] as $uri=>$route){
                if(trim($uri,'/') == trim($path,'/')){
                    $this->action = $route;
                    break;
                }
            }
            return $this;
        }
    
        /**
         * 执行路由
         * @param $request
         */
        public function runRoute($request){
            //测试匹配路由是否成功
            //var_dump($this->action);
            if($this->action instanceof \Closure){
                //如果是闭包直接执行
                ($this->action)();
            }
    
            //如果是字符串,这里只对Controller的类型进行处理
            if(is_string($this->action)){
                $this->runController();
            }
        }
    
    
        /**
         * 执行控制器方法
         */
        protected function runController(){
            $class = $this->getController();
            $method = $this->getMethod();
            //执行对应的控制器方法
            $class->$method();
        }
    
        protected function getController(){
            if (!$this->controller){
                $class = $this->namespace.'\\'.explode('@',$this->action)[0];
    
                $this->controller = $this->app->make(ltrim($class,'\\'));
            }
    
            return $this->controller;
        }
    
        protected function getMethod(){
            return explode('@',$this->action)[1];
        }
    
        /**
         * 设置控制器的命名空间,在Route的服务提供者中调用进行配置
         * @param $namespace
         * @return $this
         */
        public function setNamespace($namespace){
            $this->namespace = $namespace;
            return $this;
        }
    }
    
    //route facade
    <?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2020/11/14 0014
     * Time: 19:42
     */
    
    namespace Slaravel\Support\Facades;
    
    
    use Slaravel\Route\Router;
    
    class Route extends Facade
    {
        public static function getFacadeAccessor()
        {
            echo 'route facades '.Router::class;
            return 'Route';
        }
    }
    
    <?php
    
    namespace App\Providers;
    
    use App\Http\Controller\Hello;
    use Slaravel\Support\Facades\Route;
    use Slaravel\Support\ServiceProvider;
    
    class RouteServiceProvider extends ServiceProvider
    {
    
        protected $namespace='\App\Http\Controller';
    /*    public $bindings = [
            'test' =>
        ];*/
    
        public function register(){
            echo 'Route 服務提供者的 register'.PHP_EOL;
            //app 类注入Router
            $this->app->instance('Route',$this->app->make('Route',[$this->app]));
        }
    
        public function boot(){
            echo 'Route 服務提供者的 boot'.PHP_EOL;
            //获取路由文件
            Route::setNamespace($this->namespace)->register($this->app->getBasePath().'/routes/routes.php');
        }
    
    }
    

    相关文章

      网友评论

          本文标题:手写一个laravel(七) 路由实现

          本文链接:https://www.haomeiwen.com/subject/swdvwktx.html