手写一个laravel(七) 路由实现
- 创建Route/Router.php 为路由的实现类,实现get,any等方法
- 在Application的registerCoreContainerAliases中进行绑定
- 在Support的Facades下创建Route.php,将路由类可以使用门面加载
- 在RouteServicePrivoder的boot方法中调用register,传递路由路径
- 路由匹配 index.php->Kernel.php->haandle()->Router.php->dispatcher()->find()->match()
- 路由执行,如果是一个控制器,需要设置控制器的命名空间,在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');
}
}
网友评论