Magento 2 Templates – Use $block or $this?

magento2phtmltemplate

In Magento 2, the $this variable no longer refereces to a template's block object. It refers to a template class

 Magento\Framework\View\TemplateEngine\Php

However, this template class has a passthrough __call method

#File: vendor/magento/framework/View/TemplateEngine/Php.php
public function __call($method, $args)
{
    return call_user_func_array([$this->_currentBlock, $method], $args);
}

Which ensure any method calls make it through to the actual block. This also explains why you can't call protected methods from phtml templates.

In addition to this though, every (I think?) template has a variable named $block populated, which also refers to the parent block object. You can see this in use in Magento's list template

#File: vendor/magento/module-catalog/view/frontend/templates/product/list.phtml
//...
$_productCollection = $block->getLoadedProductCollection();

where the $block variable is used, but never explicitly defined.

Other than the differences mentioned above, is there any difference between using one technique over the other? i.e. Do both $block and $this->currentBlock refer to the same object?

Best Answer

In a template file, $block and $this->_currentBlock are the same thing.

Take a look at the render method in the Php.php template engine.
Before including the template file, this happens: $this->_currentBlock = $block; then the template file is included using a simple include $fileName;.
This means that inside a template you are still inside the Php template engine. That's why $this works, and that's why $block is defined.

[EDIT]
I just found out that using $this inside templates is discouraged.
The php sniffer with the EcgM2 standards shows a warning when using $this inside templates.
Replacing $this with $block makes the warning go away.

Related Topic