Magento 2 路由映射

3,041次阅读
没有评论

共计 9553 个字符,预计需要花费 24 分钟才能阅读完成。

Magento 2 路由映射

路由是Magento最重要的一部分。完整的Magento 2应用流由依靠处理URL请求和负责匹配和处理这些请求的路由类组成。在这篇文章中我们就讨论下Magento 2 的路由流,并且拣几个默认安装后自带的路由做一下分析。顺便展示一下如何创建自定义路由。路由如何匹配动作 (Controller class), 更多地信息,将来会另开一片文章说道说道。

路由流

首先,我们要有一个完整的路由流得概念,然后再后面才能深入探讨细节。我们都知道,Magento2创建HTTP请求的方式就是那里请求就在那里创建。 我们的路由流随着前端控制器的创建而开始。

[php]$frontController = $this->_objectManager->get(‘Magento\Framework\App\FrontControllerInterface’);
[/php]

前端控制器负责对循环槽的所有可用的路由器和当前请求匹配责任路由器,稍后我们将介绍前端控制器的细节。目前,要了解完整的流程之前,最重要的是需要知道如何应用如何与路由器匹配的。路由器列表在RouterList类(称为前端控制器循环路由器),位于Magento\Framework\App,这个类是负责对路由器列表进行排序和迭代。路由器类负责匹配,如果该路由器负责当前请求。让我们来看看Magento2流:

index.php (runs bootstrap and create HTTP application) → HTTP app → FrontController → Routing → Controller processing → etc

为了更好的理解Magento 2的路由,我们挨个分析路由路径的每个部分。

前端控制器

与Magento 1相同,它是HTTP应用程序启动(启动方法)入口路由点。它负责匹配路由器的当前请求。位于lib/internal/Magento/Framework/App/FrontController.php。你可以看到FrontControllerInterface在HTTP中的应用。让我们来看看代码:

[php]

class Http implements \Magento\Framework\AppInterface
{
public function launch()
{

//Here Application is calling front controller and it’s dispatch method
$frontController = $this->_objectManager->get(‘Magento\Framework\App\FrontControllerInterface’);
$result = $frontController->dispatch($this->_request);

}
}

[/php]

现在,当我们知道如何和何时前端控制器被调用,我们再来看看前端控制器类和调度方法本身试怎么用的:

[php]
lib/internal/Magento/Framework/App/FrontController.php
class FrontController implements FrontControllerInterface
{
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);
$actionInstance->getResponse()->setNoCacheHeaders();
$result = $actionInstance->dispatch($request);
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;
}
}
[/php]

我们可以看到,调度方法在所有路由器(已启用的,我们稍后再路由器配置)中循环,直到一个找到匹配的路由器,并且请求被分派($request→setDispatched(true);)或路由循环计数器超过100。路由器可以匹配的,否则它会重复循环这个匹配过程。此外,路由器可以重定向和分派,同时它也可以被匹配和处理。路由器列表类在请求流中被编译。现在,我们继续看看路由器匹配(匹配方法)的工作原理,以及究竟是什么路由器。

路由

路由是负责匹配和处理URL请求的PHP类。通常来讲,Magento框架和核心都包含一些路由:例如 Base, DefaultRouter, Cms and UrlRewrite. 我们后面会挨个讲解他们的用途和工作原理. 路由用于路由接口交互RouterInterface. 我们先看看这个默认的路由:

Base Router → CMS Router → UrlRewrite Router → Default Router

(这就是路由循环 – FrontController::dispatch())

Base Router

位于lib/internal/Magento/Framework/App/Router/Base.php, 是循环中第一个路由,如果你是Magento1的开发者,你就明白他是起始路由。 匹配方法会解析请求和匹配行动,后者会设置模块前端名、控制器路径名、动作名、控制模块和路由名。 Base Router中MagentoURL (front name/action path/action/param 1/etc params/) 被匹配。

CMS Router

CMS Router 位于 app/code/Magento/Cms/Controller/Router.php,用于处理 CMS页面,将模块名字设置为 (module front name) 为“cms”, 控制器名字 (controller path name) 为“page” ,动作名字为 “view” – app/code/Magento/Cms/Controller/Page/View.php 控制器。设置好Base controller,会继续设置页面ID并转发,但不会分发。转发的意思是它会打破现有路由循环并重启当前循环 (it can do that 100 times max)。 该路由会匹配激活 View controller in Cms/Controller/Page 的Base Router,同时展示以保存的页面ID (found page ID depending on url).

UrlRewrite Router

Magnto 2  UrlRewrite有自己的路由, 你可能会想起Magento1中Url Rewrite就是Standard router的一部分,位于: app/code/Magento/UrlRewrite/Controller/Router.php ,他使用Url Finder来从数据库获取 匹配 url的 url rewrite:

[php]
$rewrite = $this->urlFinder->findOneByData(
[
UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(),
UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(),
UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(),
UrlRewrite::IS_AUTOGENERATED => 1,
]
);
[/php]

它会和CMS router一样执行转发动作。

Default Router

位于 lib/internal/Magento/Framework/App/Router/DefaultRouter.php存在于整个路由循环中。当其他Router都没有匹配的时候,就需要他出场了。Magento2中我们创建custom handle 来执行“Not found” 页面显示定义的内容。 这是一个DefaultRouter循环中没有route handler list的例子:

[php]
foreach ($this->noRouteHandlerList->getHandlers() as $noRouteHandler) {
if ($noRouteHandler->process($request)) {
break;
}
}
[/php]

Custom Router (with an example)

Front Controller 会通过routersList 中的所有路由(created from configuration in routes.xml), 所以我们需要在 lib/internal/Magento/Framework/App/RouterList.php 中定义新路由,方法为在di.xml 中增加新路由的配置文件。我们创建一个新模块 (假设名字为 Inchoo/CustomRouter),然后在routersList 增加新路由,最后创建路由类。

Custom router is just an example in which you can see how to match and forward request for Base router to match. First, we need to create folder structure for our module which is located in app/code/Inchoo/CustomRouter, and then we’ll create module.xml in etc folder and composer.json in module root with module informations. Now, we can create custom router by adding configuration to di.xml in etc/frontend folder because we want to have custom router only for frontend. Lastly, we’ll create Router.php in Controller folder with logic for matching router. We will search the URL and check if there is specific word in URL and then, depending on that word, we will set module front name, controller path name, action name and then forward request for base controller. We’ll search for two words: “examplerouter” and “exampletocms”. On “examplerouter” match, we will forward to Base router match format (by setting module front name to “inchootest”, controller path name to “test”, action name to “test”), and on “exampletocms”, we will forward to Base router to display About us page.

di.xml (located in etc/frontend)

[php]
<?xml version=”1.0″?>
<!– /** * Copyright © 2015 Inchoo d.o.o. * created by Zoran Salamun(zoran.salamun@inchoo.net) * Module is created for Custom Router demonstration */ –>
<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd”>
<type name=”Magento\Framework\App\RouterList”>
<arguments>
<argument name=”routerList” xsi:type=”array”>
<item name=”inchoocustomrouter” xsi:type=”array”>
<item name=”class” xsi:type=”string”>Inchoo\CustomRouter\Controller\Router</item>
<item name=”disable” xsi:type=”boolean”>false</item>
<item name=”sortOrder” xsi:type=”string”>22</item>
</item>
</argument>
</arguments>
</type>
</config>
[/php]

Router.php (located in Controller folder)

[php]
<?php
namespace Inchoo\CustomRouter\Controller;

/**
* Inchoo Custom router Controller Router
*
* @author Zoran Salamun <zoran.salamun@inchoo.net>
*/
class Router implements \Magento\Framework\App\RouterInterface
{
/**
* @var \Magento\Framework\App\ActionFactory
*/
protected $actionFactory;

/**
* Response
*
* @var \Magento\Framework\App\ResponseInterface
*/
protected $_response;

/**
* @param \Magento\Framework\App\ActionFactory $actionFactory
* @param \Magento\Framework\App\ResponseInterface $response
*/
public function __construct(
\Magento\Framework\App\ActionFactory $actionFactory,
\Magento\Framework\App\ResponseInterface $response
) {
$this->actionFactory = $actionFactory;
$this->_response = $response;
}

/**
* Validate and Match
*
* @param \Magento\Framework\App\RequestInterface $request
* @return bool
*/
public function match(\Magento\Framework\App\RequestInterface $request)
{
/*
* We will search “examplerouter” and “exampletocms” words and make forward depend on word
* -examplerouter will forward to base router to match inchootest front name, test controller path and test controller class
* -exampletocms will set front name to cms, controller path to page and action to view
*/
$identifier = trim($request->getPathInfo(), ‘/’);
if(strpos($identifier, ‘exampletocms’) !== false) {
/*
* We must set module, controller path and action name + we will set page id 5 witch is about us page on
* default magento 2 installation with sample data.
*/
$request->setModuleName(‘cms’)->setControllerName(‘page’)->setActionName(‘view’)->setParam(‘page_id’, 5);
} else if(strpos($identifier, ‘examplerouter’) !== false) {
/*
* We must set module, controller path and action name for our controller class(Controller/Test/Test.php)
*/
$request->setModuleName(‘inchootest’)->setControllerName(‘test’)->setActionName(‘test’);
} else {
//There is no match
return;
}

/*
* We have match and now we will forward action
*/
return $this->actionFactory->create(
‘Magento\Framework\App\Action\Forward’,
[‘request’ => $request]
);
}
}
[/php]

routes.xml (located in etc/frontend)

[php]
<?xml version=”1.0″?>

<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd”>
<router id=”standard”>
<route id=”inchootest” frontName=”inchootest”>
<module name=”Inchoo_CustomRouter” />
</route>
</router>
</config>
[/php]

Test.php (test controller action class)

[php]
<?php
/**
* Copyright © 2015 Inchoo d.o.o.
* created by Zoran Salamun(zoran.salamun@inchoo.net)
*/
namespace Inchoo\CustomRouter\Controller\Test;

class Test extends \Magento\Framework\App\Action\Action
{
/**
* Listing all images in gallery
* -@param gallery id
*/
public function execute()
{
die(“Inchoo\\CustomRouter\\Controller\\Test\\Test controller execute()”);
}
}
[/php]

You can see example module on:
https://github.com/zoransalamun/magento2-custom-router

Installation安装:

第一步配置指针:

composer config repositories.inchoocustomrouter vcs git@github.com:zoransalamun/magento2-custom-router.git

请求新的包:

composer require inchoo/custom-router:dev-master

启用 Inchoo CustomRouter模块

php bin/magento module:enable Inchoo_CustomRouter

刷新缓存:

php bin/magento setup:upgrade

现在,你对Magento 2 的Router有什么感觉呢?

欢迎在评论中分享你的想法。

正文完
 0
评论(没有评论)

空瓶子部落

文章搜索
推荐阅读
你还在5000公里换机油吗?一个没有被揭穿的秘密!

你还在5000公里换机油吗?一个没有被揭穿的秘密!

如果有汽车润滑油厂家建议发动机的换油周期是15000公里或1年,请问你会质疑吗?究其原因,多是因为大家对这个1...
一个质量攻城狮的SPC学习经验分享

一个质量攻城狮的SPC学习经验分享

导语:作为一名合格的质量攻城狮,SPC统计过程控制理论不得不通晓,因为SPC学习是质量管理学中最重要的学科之一...
正态分布及3σ原则

正态分布及3σ原则

相信很多人都对正态分布及3σ原则感兴趣,这篇文章就来简单的讲解一下: [embeddoc url=”...
普通人自我跃迁和财富升级的关键技巧:OODA循环(万字完全指南)

普通人自我跃迁和财富升级的关键技巧:OODA循环(万字完全指南)

1997 年 3 月 20 日,一群人聚集在阿灵顿国家公墓的旧邮政教堂,参加美国空军退役上校约翰・理查德・博伊...
测量高手放大招:圆跳动测量技巧总结

测量高手放大招:圆跳动测量技巧总结

01. 前言 在五金机加工厂实际的测量工作中,经常碰到要求测量两个要素的圆跳动问题, 利用不同的测量辅件及夹具...
最新文章
群晖 Let’s Encrypt 泛域名证书自动更新

群晖 Let’s Encrypt 泛域名证书自动更新

目前acme协议版本更新,开始支持泛域名(wildcard),也就是说,可以申请一个类似*.domain.co...
可以卸载TV Box 了,这款支持「绅士模式」的影视神器你值得拥有

可以卸载TV Box 了,这款支持「绅士模式」的影视神器你值得拥有

还在为找优秀片源难、广告多、平台会员太贵而烦恼?今天给大家挖到一款真正的影视宝藏工具——小猫影视! 作为开源免...
【收藏】一次性解决TV点播/直播自由

【收藏】一次性解决TV点播/直播自由

很多时候,资源就在面前,但是我们视而不见,因为长久的安逸,已经让人失去动手的兴趣。但是每次我需要挨个切换APP...
OpenWrt 存储空间扩容的两种方案

OpenWrt 存储空间扩容的两种方案

说明:当我们通过群晖 VMM 虚拟机安装 Open­Wrt 时,默认会分配一个 10GB 的存储空间,而实际情...
OpenWrt修改IP地址两种方法(直接命令修改跟后台修改)

OpenWrt修改IP地址两种方法(直接命令修改跟后台修改)

OpenWrt是什么?OpenWrt一般常见于无线路由器(软路由)第三方固件,它是一个高效、可靠、功能多的路由...
热门文章
提高过程能力指数(CP/CPK)的途径

提高过程能力指数(CP/CPK)的途径

编者按:过程能力指数(CP/CPK)想必各位质量人都耳熟能详、运用自如,质量工程师之家前期也共享过数篇关于过程...
SPC控制图的八种模式分析

SPC控制图的八种模式分析

SPC控制图有八种模式,即八种判断异常的检验准则,每一种检验准则代表一种异常现象,应用SPC控制图进行过程评估...
测量高手放大招:圆跳动测量技巧总结

测量高手放大招:圆跳动测量技巧总结

01. 前言 在五金机加工厂实际的测量工作中,经常碰到要求测量两个要素的圆跳动问题, 利用不同的测量辅件及夹具...
过程能力分析(CP&cpk)

过程能力分析(CP&cpk)

引入过程能力分析的目的? 在我们现有的管理过程中,我们经常会遇到有些具体指标总是不尽人意,存在许多需要改进的地...
新能源汽车 “两会”精神宣贯会

新能源汽车 “两会”精神宣贯会

此次和大家分享新能源汽车相关政策: [embeddoc url=”https://www.ctro...
最新评论
多乐士 多乐士 通过摸索发现ssh拉取会报错,直接网页访问下载会报404错误,不知道原因;但是可以通过群晖CM注册表访问下载,其方法如下: Container Manager-注册表-设置-新增-注册表名称随便写,注册表URL填你的加速地址,勾选信任的SSL自我签署证书,登录信息不填-应用-使用你的地址,这是注册表会显示了,在搜索栏中输入映像名称,搜索结果在每一页的最后一个,你需要划到最后一个进行下载,实测可正常下载安装。 以上供网友参考。
多乐士 多乐士 还有一个比较简单的方法,只是需要一些外部工具。 1、讲损毁硬盘取出,装入外部移动硬盘 2、打开Diskgenius,定位到硬盘 3、格式化系统分区 4、重新插入硬盘 5、存储池->修复存储池即可
多乐士 多乐士 写的不错的文章
辞了老衲 辞了老衲 这个确实有帮助。
渋驀 渋驀 当然任何时候都可以用curl命令和crontab来实现动态更新DDNS的ip地址: 1、安装crontab之后为root用户创建文件/var/spool/cron/root 2、创建并配置ddnsupdate.sh,放到/usr/bin/文件下,文件内容(以he.net为例): Autodetect my IPv4/IPv6 address: IPV4:curl -4 "http://dyn.example.com:password@dyn.dns.he.net/nic/update?hostname=dyn.example.com" IPV6:curl -6 "http://dyn.example.com:password@dyn.dns.he.net/nic/update?hostname=dyn.example.com" 3、添加执行权限chomod +x /usr/bin/ddnsupdate.sh 4、编辑root用户的crontab:*/10 * * * * /usr/binddnsupdate.sh,每10分钟执行一次。好了,可以享受你的DDNS了
21410 21410 请问下载链接在那里?
madkylin madkylin 不错,不错,谢谢分享了,好东西啊 :lol:
feilung feilung 求方法
zengsuyi zengsuyi 应该挺不错的
zise zise 看看是怎么操作的。。 :oops: