Question

I may be missing a point but I'm just wondering why sometimes there is an "use" statement for a specific class and sometimes we don't.

Example: app\code\Magento\Email\Model\Template.php, we have at the top of file:

namespace Magento\Email\Model;

use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;

Then in the __construct method we have the following parameters:

public function __construct(
    \Magento\Framework\Model\Context $context,
    \Magento\Framework\View\DesignInterface $design,
    \Magento\Framework\Registry $registry,
    \Magento\Store\Model\App\Emulation $appEmulation,
    StoreManagerInterface $storeManager,
    \Magento\Framework\View\Asset\Repository $assetRepo,
    \Magento\Framework\Filesystem $filesystem,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Email\Model\Template\Config $emailConfig,
    \Magento\Email\Model\TemplateFactory $templateFactory,
    \Magento\Framework\Filter\FilterManager $filterManager,
    \Magento\Framework\UrlInterface $urlModel,
    \Magento\Email\Model\Template\FilterFactory $filterFactory,
    array $data = []
)

So we can clearly see that as we called use Magento\Store\Model\StoreManagerInterface; at the top of the class, we are able to do StoreManagerInterface $storeManager in the constructor parameters.

My questions are:

  • Why do we do this for only one class?
  • Why can't we add a use statement for every class of the constructor so we don't have to type the full class path ?
  • Or the other way around, why don't we get rid of the use statement and type the full path to StoreManagerInterface class ?
Was it helpful?

Solution

There is no technical reason to prefer one over the other, except if there are name conflicts (like different "Context" classes). But those can be solved with aliases and that's what I usually do:

use Magento\Framework\Model\Context as ModelContext;

I assume that in the core many methods, especially the constructors, were generated by tools like the conversion tool at first and then later not changed to use "use" imports.

So I'd suggest that in your own code you always import classes with "use" to make the actual code less verbose and more readable.

OTHER TIPS

The usage depends on specific situation. My approach is:

Class mentioned just once inside a file - FQN

Leave fully qualified name. This improves readability because you don't need to look at use section again.

Class name used multiple times - import

Put it in a use section. This makes the code shorter where the class is mentioned.

Class used once but I need a short notation - import

Better explain with an example.

FQN

$collection->getSelect()
           ->joinInner(['campaign_products' => $subSelect],
               'campaign_products.product_id = e.entity_id',
               [self::FIELD_SORT_ORDER => "IFNULL(IF(0 = " . \Custome\Module\Api\Data\ProductListInterface::SORT_ORDER . ", NULL, " . \Custome\Module\Api\Data\ProductListInterface::SORT_ORDER . "), {$defaultSortValue})"]
           );

import

$collection->getSelect()
           ->joinInner(['campaign_products' => $subSelect],
               'campaign_products.product_id = e.entity_id',
               [self::FIELD_SORT_ORDER => "IFNULL(IF(0 = " . ProductListInterface::SORT_ORDER . ", NULL, " . ProductListInterface::SORT_ORDER . "), {$defaultSortValue})"]
           );

In my opinion the 2nd example is easier to read. (But honestly speaking I'd prefer to use variables instead of constants here to give it even more readability.)

Magento 2 API Interfaces

There is a notice regarding M2 auto-exposed API endpoints. In interfaces used for REST/SOAP methods you should always use FQNs.

The annotations are parsed by the Magento Framework to determine how to convert data to and from JSON or XML.

Class imports (that is, use statements above the class) are not applied!

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top