{ Hello Magento 2 }

解决 Magento 2 应用问题,更注重深度挖掘。(ง •̀_•́)ง

0%

Magento 2 Templates: Use $block or $this

在 Magento 2 的 templates 中使用 $block 还是 $this ? 结论:$block$this 指向同一个 block 对象,但是建议使用 $block 不建议使用 $this。 在 M2 的 template 中,$this 指向的不再是该 template 的 block 对象,而是一个 template 类:Magento\Framework\View\TemplateEngine\Php 以之前的 ThankIT_HelloWorld 模块为基础,修改以下文件,进行实验。 File:app\code\ThankIT\HelloWorld\view\frontend\templates\index\index.phtml

1
2
3
4
5
6
7
8
9
Welcome to hellomagento2.com
<?php
echo '<br/>';
echo get_class($this);
echo '<br/>';
echo $block->sayHello();
echo '<br/>';
// discouraged
echo $this->sayHello();

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

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
namespace ThankIT\HelloWorld\Block\Index;

use Magento\Framework\View\Element\Template;

class Index extends Template
{
# ... other code
public function sayHello()
{
return __('Hello World');
}
#... ohter code ...

那么访问我们的 url http://example.com/helloworld/index/index/ 得到的类名正是 Magento\Framework\View\TemplateEngine\Php 查看该类的以下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Redirects methods calls to the current block
*
* This is needed because the templates are included in the context of this engine
* rather than in the context of the block.
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array([$this->_currentBlock, $method], $args);
}

这就解释了为什么我们可以通过 $this 来调用 block 中的方法。 查看该类的以下方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* Render output
*
* Include the named PHTML template using the given block as the $this
* reference, though only public methods will be accessible.
*
* @param BlockInterface $block
* @param string $fileName
* @param array $dictionary
* @return string
* @throws \Exception
*/
public function render(BlockInterface $block, $fileName, array $dictionary = [])
{
ob_start();
try {
$tmpBlock = $this->_currentBlock;
$this->_currentBlock = $block;
extract($dictionary, EXTR_SKIP);
include $fileName;
$this->_currentBlock = $tmpBlock;
} catch (\Exception $exception) {
ob_end_clean();
throw $exception;
}
/** Get output buffer. */
$output = ob_get_clean();
return $output;
}

include $fileName; 前,$this->_currentBlock = $block ,而在 template 中,$block$this->_currentBlock 是一样的。这就解释了为什么我们可以通过 $block 来访问 block 中的方法。 但是 The php sniffer with the EcgM2 standards 不建议使用 $this ,所以我们还是用 $block 吧。

参考网址

Magento 2 Templates: Use $block or $this?