(Routing in Laravel Notes) How does Laravel implement routing functions and split routing

How does Laravel implement routing to call controller methods and closure methods

This article is written in more detail. Interested friends can click on this link in layman's language to perform routing principles Laravel view.

Not much to say, go directly to the underlying code of Laravel: Path: vendor\laravel\framework\src\Illuminate\Routing\Route.php

<?php
    /**
     * Create a new Route instance.  创建一个Route实例。
     *
     * @param  array|string  $methods
     * @param  string  $uri
     * @param  \Closure|array  $action
     * @return void
     */
    public function __construct($methods, $uri, $action)
    {
    
    
        $this->uri = $uri;
        $this->methods = (array) $methods;
        $this->action = $this->parseAction($action);

        if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {
    
    
            $this->methods[] = 'HEAD';
        }

        if (isset($this->action['prefix'])) {
    
    
            $this->prefix($this->action['prefix']);
        }
    }

    /**
     * Parse the route action into a standard array.  将路线动作解析成数组。
     *
     * @param  callable|array|null  $action
     * @return array
     *
     * @throws \UnexpectedValueException
     */
    protected function parseAction($action)
    {
    
    
        return RouteAction::parse($this->uri, $action);
    }

    /**
     * Run the route action and return the response.   运行route操作并返回响应。
     *
     * @return mixed
     */
    public function run()
    {
    
    
        $this->container = $this->container ?: new Container;

        try {
    
    
            if ($this->isControllerAction()) {
    
    
                return $this->runController();
            }

            return $this->runCallable();
        } catch (HttpResponseException $e) {
    
    
            return $e->getResponse();
        }
    }

    /**
     * Checks whether the route's action is a controller.  
     *
     * @return bool
     */
    protected function isControllerAction()   //确定动作是否是控制器
    {
    
    
        return is_string($this->action['uses']);
    }

    /**
     * Run the route action and return the response. 
     *
     * @return mixed
     */
    protected function runCallable()   //执行动作并且返回 响应
    {
    
    
        $callable = $this->action['uses'];

        return $callable(...array_values($this->resolveMethodDependencies(
            $this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses'])
        )));
    }

    /**
     * Run the route action and return the response.
     *
     * @return mixed
     *
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
     */
    protected function runController()  //执行路由动作并且返回响应
    {
    
    
        return $this->controllerDispatcher()->dispatch( // 将请求分配给指定的控制器和方法。
            $this, $this->getController(), $this->getControllerMethod()
        );
    }

    /**
     * Get the controller instance for the route. 
     *
     * @return mixed
     */
    public function getController()   // 获取执行的控制器
    {
    
    
        if (! $this->controller) {
    
    
            $class = $this->parseControllerCallback()[0];
            $this->controller = $this->container->make(ltrim($class, '\\'));
        }

        return $this->controller;
    }

    /**
     * Get the controller method used for the route.
     *
     * @return string
     */
    protected function getControllerMethod()  // 获取控制器执行的方法
    {
    
    
        return $this->parseControllerCallback()[1];
    }

    /**
     * Parse the controller.
     *
     * @return array
     */
    protected function parseControllerCallback()  //解析控制器, 分解成控制器类以及操作的方法
    {
    
    
        return Str::parseCallback($this->action['uses']);
    }

    /**
     * Get the dispatcher for the route's controller.  
     *
     * @return \Illuminate\Routing\Contracts\ControllerDispatcher
     */
    public function controllerDispatcher()   //获取路由控制器的调度程序。
    {
    
    
        if ($this->container->bound(ControllerDispatcherContract::class)) {
    
    
            return $this->container->make(ControllerDispatcherContract::class);
        }

        return new ControllerDispatcher($this->container);
    }

The above only lists a few methods at the bottom. If you want to know the specific implementation steps, you can hit the dd() breakpoint to experience it by yourself. Pay attention to clear the breakpoint after you hit it! ! !

Split routing

Laravel's routing is mainly placed in the routes folder under the project root directory. Laravel has allocated two routing files, api.php and web.php, for us, which is obviously not enough in our development process. So we need to split out a separate routing file so that we can manage and maintain routing.
The following are examples of splitting web.php, and API routing is the same.

method one:

  1. Create a new web/user.php in the same directory as web.php

Insert picture description here
2. In web.php require_once ('web/user.php'); import the file
Insert picture description here

3. Then you can write the route directly in user.php
Insert picture description here

Method Two:

  1. Open the file: app\Providers\RouteServiceProvider.php

2. Modification: boot() method

public function boot()
    {
    
    
        //匹配通用路由地址
        $pattern = __DIR__ . '/../Http/Routes/*.php';
        foreach (glob($pattern) as $route) {
    
    
            require_once $route;
        }
        parent::boot();
    }
  1. Then create a new folder app\Http\Routes
  2. Create routing file user.php under app\Http\Routes
    Insert picture description here
    so that routing can also be implemented.
    Visit: your domain name /user/login

Guess you like

Origin blog.csdn.net/qq_39004843/article/details/105639681