Magento 2 中的 Controller

本篇围绕 Magento 2 的 Controller ,介绍控制器是怎么工作的,怎么创建,它和 layout 配置文件配合,怎么输出一个页面,以及控制器中经常用到的两个方法 _redirect()_forward()

控制器在 Magento 2 中是很重要的,一般而言,对 PHP MVC 框架来说也是很重要的。它的功能是接受请求,处理请求和呈现页面(render page)。

模块的 Controller 目录下有一个或多个文件,每个文件都是一个单独的 class ,每个 class 都有一个 execute 方法。Magento 2 中有两种类型的控制器,一种是前台控制器,另一种是后台控制器。他们大体上是一样的流程,后台控制器稍微特别点,它拥有一个检查权限的方法。

控制器怎么工作的?

它从终端用户(浏览器或命令行)接受请求,比如:

http://example.com/route_name/controller/action
  • route_name 是一个在 routes.xml 中设置的唯一名称
  • controller 是 Controller 目录下的文件夹
  • action 是一个有 execute 方法的 class

Magento 2 系统中处理请求,路由到对应控制器的类是 frontController (Magento\Framework\App\FrontController)
看代码:

foreach ($this->_routerList as $router) {
   try {
      $actionInstance = $router->match($request);
   …
}

如果找到匹配的 action 类,那么就会执行其中的 execute 方法。

如何创建控制器

如果还不清楚怎么创建模块,请参考 创建 Magento 2 Hello World Simple Module。本篇以该文中创建的模块为基础。该文末尾可以找到对应的代码下载地址,可以下载后跟着本文的步骤做。本文末尾也附带完成后的代码供比对。

要创建控制器,首先需要在模块目录下创建 Controller 目录。
假设我们在 ThankIT_HelloWorld 模块的基础上创建一个 Index controller 和一个 Index action

创建 routes.xml

File: 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">
    <router id="standard">
        <route frontName="helloworld" id="helloworld">
            <module name="ThankIT_HelloWorld"/>
        </route>
    </router>
</config>

创建控制器

File: Controller/Index/Index.php

<?php
namespace ThankIT\HelloWorld\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action {

    protected $resultPageFactory;

    /**
     * Constructor
     *
     * @param \Magento\Framework\App\Action\Context  $context
     * @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        parent::__construct($context);
    }

    /**
     * Execute view action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        return $this->resultPageFactory->create();
    }
}

所有 controller 都必须继承自 \Magento\Framework\App\Action\Action 该类有 dispatch 方法,就是 dispatch 方法会调用 execute 方法。在 execute 方法中我们放控制器的逻辑并返回响应结果。

创建 layout 文件

File: view/frontend/layout/helloworld_index_index.xml

<?xml version="1.0" ?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="ThankIT\HelloWorld\Block\Index\Index" name="index.index" template="ThankIT_HelloWorld::index/index.phtml"/>
        </referenceContainer>
    </body>
</page>

创建 Block

File: app\code\ThankIT\HelloWorld\Block\Index\Index.php

<?php
namespace ThankIT\HelloWorld\Block\Index;
use Magento\Framework\View\Element\Template;

class Index extends Template
{

}

创建 template

File: view/frontend/templates/index/index.phtml

Welcome to hellomagento2.com

刷新缓存

命令行:

php bin/magento cache:flush

测试

浏览器中打开http://<yourhost.com>/helloworld/index/index 或者 http://<yourhost.com>/helloworld/

我们就可以看到结果了,这次不是纯字符串哦。

How to create Controllers in Magento 2

Permission – ACL

参考 Magento 2 Admin ACL Access Control Lists

Magento 2 控制的其他方法

Forward method

_forward() protected 方法会将请求转向其他 controller/action 但是用户在浏览器中看到的 URL 是不变的。

例如:
File: Controller/Index/Forward.php

<?php
namespace ThankIT\HelloWorld\Controller\Index;

class Forward extends \Magento\Framework\App\Action\Action
{
    public function execute()
    {
        $this->_forward('index');
    }
}

创建好以后 cache:flush 然后访问 http://<yourhost.com>/helloworld/index/forward 会看到和访问 http://<yourhost.com>/helloworld/index/index 一样的结果,但是我们的 url 并没有改变。

_forward() 还有其他参数:

function _forward($action, $controller = null, $module = null, array $params = null)

其中的 $module 指的是 route_name 对应在 routes.xml 中设置的唯一名称。

Redirect method

_redirect() 除了会会将请求转向其他 controller/action ,响应的 URL 也会发生改变。

可将上述例子中的 $this->_forward('index'); 改成 $this->_redirect('*/*/index'); 查看效果。

参考文档

how to create Controllers in Magento 2

代码下载

相关代码下载

发表评论

电子邮件地址不会被公开。 必填项已用*标注