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

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

<?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
查看该类的以下方法:

    /**
     * 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 中的方法。

查看该类的以下方法

    /**
     * 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?

发表评论

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