marcus-ma / myBlog

写写开发笔记

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

论如何实现一个低配版的路由组件

marcus-ma opened this issue · comments

如果尝试过laravel开发,应该对下面的代码不陌生:

Route::get('foo', function () {
    return 'Hello World';
});

这是laravel独特的路由定义方法,这种方法TP5也有所借鉴到。laravel文档对上面的描述是:

最基本的 Laravel 路由只接收一个 URI 和一个闭包,并以此提供一个非常简单且优雅的定义路由方法。

以前就一直很好奇,这种写法到底是如何实现的,试过观摩源码,发现laravel的文件目录太多,找起来很费事,就一直卡在那里。直到早段时间借阅了《Modern PHP》这本书,里面刚好有一段就是阐述了上面路由写法的基本实现原理,源码如下:

class App
{
    protected $routes = [];
    protected $responseStatus = "200 OK";
    protected $responseContentType = "text/html";
    protected $responseBody = "Hello World";

    //添加路由
    public function addRoute($routePath, $routeCallback)
    {
        //通过使用bindTo($this, __CLASS__)方法绑定类属性,使外部可以调用内部属性
        $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__);
    }

    //解析路由
    public function dispath($currentPath)
    {
        foreach ($this->routes as $routePath => $callback)
        {
            if ($routePath === $currentPath)
            {
                $callback();
            }
        }

        header('HTTP/1.1 '.$this->responseStatus);
        header('Content-type '.$this->responseContentType);
        header('Content-length'.mb_strlen($this->responseBody));
        echo $this->responseBody;
    }

    //返回路由数组
    public function get()
    {
        return $this->routes;
    }
}

$app = new App();
$app->addRoute('/user/marcus',function(){
    $this->responseContentType = 'application/json;charset=utf8';
    $this->responseBody = '{"name" : "marcus"}';
});
$app->dispath("/user/marcus");

代码里已经有注释,实现了最为基本的路由类原型,至于laravel内部的Route实现原理是什么,我也还是不太清楚,毕竟laravel里面融合太多的设计模式和前卫优秀的架构。
鉴于上面的原型,如果理解的人应该可以自己动手实现一个低配版的路由类。