Magento 2中请求路由

在本文中,我们将比较Magento 1和Magento 2 中的路由。

路线确定从搜索系统中定义的当前路线开始。该过程从这里开始:

/vendor/magento/framework/App/FrontController.php


public function dispatch(RequestInterface $request)
    {
        \Magento\Framework\Profiler::start('routers_match');
        $routingCycleCounter = 0;
        $result = null;
        while (!$request->isDispatched() && $routingCycleCounter++ < 100) {
            /** @var \Magento\Framework\App\RouterInterface $router */
            foreach ($this->_routerList as $router) {
                try {
                    $actionInstance = $router->match($request);
                    if ($actionInstance) {
                        $request->setDispatched(true);
                        $this->response->setNoCacheHeaders();
                        if ($actionInstance instanceof \Magento\Framework\App\Action\AbstractAction) {
                            $result = $actionInstance->dispatch($request);
                        } else {
                            $result = $actionInstance->execute();
                        }
                        break;
                    }
                } catch (\Magento\Framework\Exception\NotFoundException $e) {
                    $request->initForward();
                    $request->setActionName('noroute');
                    $request->setDispatched(false);
                    break;
                }
            }
        }
        \Magento\Framework\Profiler::stop('routers_match');
        if ($routingCycleCounter > 100) {
            throw new \LogicException('Front controller reached 100 router match iterations');
        }
        return $result;
    }


在方法dispatch()以及Magento 1文件app / code / core / Mage / Core / Controller / Varien / Front.php中,存在一些匹配项:

  • 检查是调度程序的请求($ request-> isDispatched());
  • 搜索匹配项($ router-> match($ request))。

与Magento 1相比,Magento 2仅确定了两个路由:

  • /vendor/magento/framework/App/Router/Base.php;
  • /vendor/magento/framework/App/Router/DefaultRouter.php。

与Magento 1相同,如果未找到路由器,则经过100次迭代后,将显示一条消息。在这里我们可以找到Magento 1的属性:

if ($routingCycleCounter > 100) {
            throw new \LogicException('Front controller reached 100 router match iterations');
        }

路由过程的主要步骤与Magento 1中的相同:

  • 确定模块
  • 确定控制器
  • 检测动作
  • 用于当前请求检测的数据

Magento 2中的路由器初始化与Magento 1中的不同:

protected function _getRoutes($scope = null)
    {
        $scope = $scope ?: $this->_configScope->getCurrentScope();
        if (isset($this->_routes[$scope])) {
            return $this->_routes[$scope];
        }
        $cacheId = $scope . '::' . $this->_cacheId;
        $cachedRoutes = unserialize($this->_cache->load($cacheId));
        if (is_array($cachedRoutes)) {
            $this->_routes[$scope] = $cachedRoutes;
            return $cachedRoutes;
        }
 
        $routers = $this->_reader->read($scope);
        $routes = $routers[$this->_areaList->getDefaultRouter($scope)]['routes'];
        $this->_cache->save(serialize($routes), $cacheId);
        $this->_routes[$scope] = $routes;
        return $routes;
    }
 
public function read($scope = null)
{
	$scope = $scope ?: $this->_defaultScope;
	$fileList = $this->_fileResolver->get($this->_fileName, $scope);
	if (!count($fileList)) {
		return [];
	}
	$output = $this->_readFiles($fileList);
 
	return $output;
}

搜索适当的路由器时发生初始化:

…
while (!$request->isDispatched() && $routingCycleCounter++ < 100) {
            /** @var \Magento\Framework\App\RouterInterface $router */
            foreach ($this->_routerList as $router) {
                try {
                    $actionInstance = $router->match($request);
                    if ($actionInstance) { 
			…

进一步的路由过程类似于Magento 1:

protected function parseRequest(\Magento\Framework\App\RequestInterface $request)
    {
        $output = [];
 
        $path = trim($request->getPathInfo(), '/');
 
        $params = explode('/', $path ? $path : $this->pathConfig->getDefaultPath());
        foreach ($this->_requiredParams as $paramName) {
            $output[$paramName] = array_shift($params);
        }
 
        for ($i = 0, $l = sizeof($params); $i < $l; $i += 2) {
            $output['variables'][$params[$i]] = isset($params[$i + 1]) ? urldecode($params[$i + 1]) : '';
        }
        return $output;
    }

前三个元素被视为主要元素。它们为当前请求定义模块,控制器和操作。

然后根据其moduleFrontName确定模块:

/**
         * Searching router args by module name from route using it as key
         */
        $modules = $this→_routeConfig→getModulesByFrontName($moduleFrontName);

然后确定当前请求的控制器和动作:

/**
         * Going through modules to find appropriate controller
         */
        $currentModuleName = null;
        $actionPath = null;
        $action = null;
        $actionInstance = null;
 
        $actionPath = $this->matchActionPath($request, $params['actionPath']);
        $action = $request->getActionName() ?: ($params['actionName'] ?: $this->_defaultPath->getPart('action'));
        $this->_checkShouldBeSecure($request, '/' . $moduleFrontName . '/' . $actionPath . '/' . $action);
 
        foreach ($modules as $moduleName) {
            $currentModuleName = $moduleName;
 
            $actionClassName = $this->actionList->get($moduleName, $this->pathPrefix, $actionPath, $action);
            if (!$actionClassName || !is_subclass_of($actionClassName, $this->actionInterface)) {
                continue;
            }
 
            $actionInstance = $this->actionFactory->create($actionClassName);
            break;
        }
 
        if (null == $actionInstance) {
            $actionInstance = $this->getNotFoundAction($currentModuleName);
            if ($actionInstance === null) {
                return null;
            }
            $action = 'noroute';
        }

此外,检查是否存在控制器文件以及先前的实现是否存储连接安全:

$this->_checkShouldBeSecure($request, '/' . $moduleFrontName . '/' . $actionPath . '/' . $action);

这意味着路由已处理。确定模块,控制器和操作。此外,正在处理针对当前请求的操作。

// set values only after all the checks are done
        $request->setModuleName($moduleFrontName);
        $request->setControllerName($actionPath);
        $request->setActionName($action);
        $request->setControllerModule($currentModuleName);
        $request->setRouteName($this->_routeConfig->getRouteByFrontName($moduleFrontName));
        if (isset($params['variables'])) {
            $request->setParams($params['variables']);
        }
        return $actionInstance;

控制元素返回以执行操作:

…
		if ($actionInstance) {
                        $request->setDispatched(true);
                        $this->response->setNoCacheHeaders();
                        if ($actionInstance instanceof \Magento\Framework\App\Action\AbstractAction) {
                            $result = $actionInstance->dispatch($request);
                        } else {
                            $result = $actionInstance->execute();
                        }
                        break;
                    }
		...

确定当前请求的输出位置。

版权属于: sbboke版权所有。

转载时必须以链接形式注明作者和原始出处及本声明。

张贴在magento2教程标签:

相关文章

0 0 投票数
文章评分
订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论