Magento 2路由

在本文中,我们将讨论Magento 2 Routing中的一个重要部分。该路线将为此我们可以在URL中使用查找模块和执行控制动作的模块定义名称。

目录

  • Magento 2请求流程
  • 在前端/管理员上创建自定义路由
    • 前端路线
      • routes.xml
    • 管理路线
    • 使用route重写控制器

Magento 2请求流程

在Magento 2中,请求URL将如下所示:

http://example.com/index.php/front_name/controller/action

在该URL中,您将看到front_name用于查找模块的URL 。路由器通过routes.xml中的define定义每个模块的名称,我们将在下面看到更多细节。

当您在Magento 2中提出请求时,它将按照此流程查找controller/action: index.php → HTTP app → FrontController → Routing → Controller processing → etc

FrontController会在HTTP中类中调用路由信息,会发现该请求controller/action匹配。

文件: 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()方法中所看到的,路由器列表将循环以查找与此请求匹配的路由器列表。如果它找到该请求的控制器操作,则将调用并执行该操作。

在前端/管理员上创建自定义路由

在这一部分中,我们将使用一个简单的模块Mageplaza_HelloWorld。请按照上一篇文章了解如何在Magento 2中创建模块。

我们将找到如何创建前端路由,管理路由以及如何使用路由重写控制器。

前端路线

Routes.xml

要注册前端路由,我们必须创建一个routes.xml文件:

文件: app/code/Mageplaza/HelloWorld/etc/frontend/routes.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <!--Use router 'standard' for frontend route-->
    <router id="standard">
        <!--Define a custom route with id and frontName-->
        <route frontName="helloworld" id="helloworld">
            <!--The module which this route match to-->
            <module name="Mageplaza_HelloWorld"/>
        </route>
    </router>
</config>

请查看代码,您将看到注册路由非常简单。您必须使用标准路由器作为前端。这条路线将有一个孩子为它定义模块和2个属性:

  • id属性是一个唯一的字符串,用于标识此路由。您将使用此字符串声明此模块操作的布局句柄
  • frontName属性也是一个唯一的字符串,它将显示在url请求中。例如,如果您声明这样的路线:
 <route frontName="helloworld" id="helloworld">

该模块的URL应该是:

http://example.com/index.php/helloworld/controller/action

此操作的布局句柄是:helloworld_controller_action.xml 因此,使用此示例路径,您必须在此文件夹中创建操作类:{namespace}/{module}/Controller/{Controller}/{Action}.php

管理路线

此路由与前端路由相同,但您必须在adminhtml文件夹中将其声明为路由器ID为admin

文件: app/code/Mageplaza/HelloWorld/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <!--Use router 'admin' for admin route -->
    <router id="admin">
        <!--Define a custom route with id and frontName -->
        <route id="mageplaza_helloworld" frontName="mageplaza_helloworld">
            <!--The module which this route match to-->
            <module name="Mageplaza_HelloWorld"/>
        </route>
    </router>
</config>

管理页面的URL与前端页面的结构相同,但是在识别这是管理员路由器admin_area之前将添加名称route_frontName。例如,admin cms页面的url :

http://example.com/index.php/admin/mageplaza_helloworld/controller/action

管理页面的控制器操作将添加到文件夹内Controller/Adminhtml。例如,对于以上网址:

{namespace}/{module}/Controller/Adminhtml/{Controller}/{Action}.php

使用route重写控制器

在这条路径中,我们将看到如何用路由器重写控制器。如上面的路径,您可以看到每个路由都有一个id属性来识别。那么如果我们定义具有相同id属性的2路由会发生什么?

答案是控制器操作将在两个模块中找到。Magento系统在配置模块排序顺序之前/之后提供属性,该顺序定义了首先找到的模块控制器。这是控制器重写的逻辑。

例如,如果我们想重写控制器customer/account/login,我们将在route.xml中定义更多路由,如下所示:

文件: app/code/Mageplaza/HelloWorld/etc/frontend/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
   <!--Use router 'standard' for frontend route-->
   <router id="standard">
        <!--Define a custom route with id and frontName-->
        <route frontName="helloworld" id="helloworld">
            <!--The module which this route match to-->
            <module name="Mageplaza_HelloWorld"/>
        </route>
       <route id="customer">
           <module name="Mageplaza_HelloWorld" before="Magento_Customer" />
       </route>
   </router>
</config>

和控制器文件: app/code/Mageplaza/HelloWorld/Controller/Account/Login.php

所以frontController 首先在我们的模块中找到Login动作,如果找到它,它将运行并且不会运行Login动作Magento_Customer。我们成功地重写了一个控制器。

您也可以使用它来使第二个模块与另一个模块具有相同的路由器。例如,通过上述声明,您可以使用路由'customer'作为控制器操作。如果您有控制器'博客'和操作'Index.php',您可以使用此网址:

http://example.com/customer/blog/index
赞(0)
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏

相关文章

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