Magento 2控制器详解[教程]

本教程翻译自:mageplaza
完整的Magento2开发中文教程请点击这里

正文:

控制器是Magento 2模块开发中的一项重要内容,也是PHP MVC框架的一个重要组成部分。它的功能是接收请求、处理和呈现页面。
在Magento 2控制器中,模块的Controller文件夹中有一个或多个文件,它包含了包含execute()方法的类的操作。有两个不同的控制器,它们是前端控制器和后端控制器。它们通常与工作流相似,但后台控制器略有不同。在后台控制器中有一个检查权限的方法。

##控制器是如何工作的?

它接受自用户的请求(命令行输入或者浏览器访问),例如:

http://example.com/route_name/controller/action
  • route_name 是在routes.xml中设置的惟一名称。
  • controller 是控制器文件夹内的文件夹。
  • action 是一个用execute方法处理请求的类。

在Magento系统中,最重要的是 frontController(Magento\App\App\frontController) ,它总是接收请求,然后路由控制器,通过 route_name的操作,让我们举一个路由请求的例子:

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

如果有控制器类的操作,**execute()**方法将运行。

##如何创建控制器

要创建控制器,我们需要在模块的controller文件夹中创建一个文件夹,并在其中声明一个action类。例如,我们为模块Magentochina_HelloWorld创建一个测试控制器和一个Hello action:

####1.创建routes.xml
路径: 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="Magentochina_HelloWorld"/>
    </route>
</router>
</config>

####2.创建控制器文件
路径: Controller/Index/Index.php

<?php 
namespace Magentochina\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();
}
}

如您所见,所有控制器都必须从 \Magento\App\Action\Action 类扩展,该类具有分派方法,它将调用Action类中的execute方法。在这个execute()方法中,我们将编写所有的控制器逻辑,并对请求返回响应。

####3.创建布局文件
路径: 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="Magento\Framework\View\Element\Template" name="index.index" template="Magentochina_HelloWorld::index/index.phtml"/>
    </referenceContainer>
</body>
</page>

####4.创建模板文件
路径: view/frontend/templates/index/index.phtml

Welcome to Magentochina.org

####5.刷新缓存

具体查看Magento2缓存管理

####6.运行测试
打开浏览器访问

http://<yourhost.com>/helloworld/index/index

或者浏览器访问:

http://<yourhost.com>/helloworld/

##权限-权限控制
在后台控制器中有一个检查权限的方法。让我们举一个例子:

protected function _isAllowed()
{
    return $this->_authorization->isAllowed('Magento_AdminNotification::show_list');
}

它将检查当前用户是否有权访问该操作,并学习更多的后台ACL访问控制列表。

##Magento 2控制器中的其他方法

#####动作(action)中的重定向(redirect)与转发(Forward )

\Magento\Framework\App\Action\Action 类提供了两个重要的方法:_forward和_redirect。

####Forward 转发方法

_forward() 保护函数将编辑请求将其传递到另一个 controller/action 类。这不会改变请求url。例如,我们有2个动作 forward和Hello World:

namespace Magentochina\HelloWorld\Controller\Test;
class Forward extends \Magento\Framework\App\Action\Action
{
public function execute()
{
	$this->_forward('hello');
}
}

如果您浏览器访问:example.com/route_name/test/forward,那么结果将在屏幕上显示:

Hello World! Welcome to Magentochina.org

您还可以在转发时更改控制器、模块和设置param。请检查**_forward()**函数以获得更多信息:

protected function _forward($action, $controller = null, $module = null, array $params = null)
{
$request = $this->getRequest();

$request->initForward();

if (isset($params)) {
    $request->setParams($params);
}

if (isset($controller)) {
    $request->setControllerName($controller);

    // Module should only be reset if controller has been specified
    if (isset($module)) {
        $request->setModuleName($module);
    }
}

$request->setActionName($action);
$request->setDispatched(false);
}

##重定向方法

此方法将传输到另一个 controller/action 类,并更改响应头和请求url。在上面的例子中,如果我们用这个**_redirect()方法替换_forward()**方法:

 $this->_redirect('*/*/hello');

当我们浏览器访问example.com/route_name/test/forward,这时浏览器URL会重定向到
example.com/route_name/test/hello 并在屏幕上显示:

 Hello World! Welcome to Magentochina.org

####翻译:西帅

辛苦博主了。
我是接着前一篇文章修改的,然后一直报resultPageFactory 的错误,清缓存也没用,最后把generated目录下的文件删了才好。
然后是<block class=“Magentochina\HelloWorld\Block\Index\Index” 会报错,因为并没有这个类,填成<block class=“Magento\Framework\View\Element\Template” 就解决了

感谢,我马上修改。。方便的话,可以把整个test的code传到github上,让其他人参考。

可以啊,不过我把模块命名都改了,不是都一样

感谢支持,后面我会继续做内容。