实例化助手在Magento 2


26

Magento 2的最新版本已经消除了Mage该类。这意味着我们已经丢失了该Mage::helper方法。

在Magento 2中是否存在用于实例化助手的替代技术(助手工厂?)?还是我们应该使用新的对象管理器类,并使用get(vs. create)将帮助程序实例化为单例/缓存对象。

Answers:


31

我看到您提出了正确的解决方案,只是想总结一下。

构造函数注入应用于在您需要的任何类中检索帮助程序(或任何其他实例):

class SomeClass
{
    public function __construct(\Magento\Core\Helper\Data $helper)
    {
        $this->helper = $helper;
    }

    public function doSmth()
    {
        $this->helper->someMethod();
    }
}

请注意,不需要phpDoc注释,Magento将直接读取构造函数签名以找出需要哪些依赖项。

\ Magento \ Core \ Helper \ Factory仅在少数情况下应使用,当您不得不调用多个助手,或者您不知道到底需要哪个助手时。

严格禁止直接使用对象管理器。因此,请避免使用:

\Magento\Core\Model\ObjectManager::getInstance()

它仅用于序列化/反序列化。


不要使用static,因为它不能用PHP单元进行测试,是的,不建议使用。所有M2依赖项都是通过构造函数完成的,并由对象管理器在内部进行管理,并将其检索为Singleton。也不要使用_来指示属性可见性,所有M2命名都应使用大写字母
PartySoft

@Anton Kril如果我们helper在模板中使用,例如$this->helper('Magento\Catalog\Helper\Image'),它遵循最佳做法吗?
Khoa TruongDinh '16

2
不,不是的。模板应仅引用块。应该避免使用帮助者
Anton Kril

10

看起来Magento鼓励人们使用其新的自动依赖项注入系统,以通过对象的构造函数将帮助程序和模型添加到对象中。

短版?如果您有一个由对象管理器实例化的对象,用PHPDoc装饰了构造函数@param并且参数设置了正确的类型提示集,则对象管理器将自动为您实例化帮助程序(或者,我相信其他对象)。

例如,以下构造函数会将一个核心数据助手注入到对象中。

/**
* @param \Magento\Core\Helper\Data $coreData
*/        
public function __construct(\Magento\Core\Helper\Data $coreData)
{
    $this->_coreHelper = $coreData;            
}

这是正确的答案-大侦探;即使经过大量挖掘,对我来说也不是很明显。
philwinkle

2
好...现在我的头好痛... 您是说我们应该使用PHPDoc来“编写”代码?这太疯狂了。我不干了。
马吕斯

@Marius haha​​ha这并不少见-Alan的博客在某种程度上对其进行了解释。
philwinkle

3
@philwinkle。我读了他的文章。非常有趣,但我仍然说这是疯狂。称我为老式,但“回到我的时代”是代码,而注释是几乎没有人愿意写的东西。
马吕斯

哦...顺便说一句。+1。好问题,好答案。
马里乌斯

7

除了上述所有答案之外,如果您必须在phtml模板中使用helper,则可以这样简单地进行操作:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]');

我希望如果有人以前不知道它会有所帮助;)


6

实例化助手的方式(至少对于新的Backend(〜dev50)模块而言)是通过helperFactory进行的:

/**
 * Return helper object
 *
 * @param string $name
 * @return \Magento\Core\Helper\AbstractHelper
 */
public function helper($name)
{
    return $this->_helperFactory->get($name);
}

本质上,这只是模型工厂的一种特殊类型。例如:Magento \ Core \ Block \ Context第143行(dev50)作为构造函数的一部分:

\Magento\Core\Model\Factory\Helper $helperFactory

帮助程序工厂将基于类名称返回请求的模型,并确保它是instanceof帮助程序抽象类:

/**
 * Get helper singleton
 *
 * @param string $className
 * @param array $arguments
 * @return \Magento\Core\Helper\AbstractHelper
 * @throws \LogicException
 */
public function get($className, array $arguments = array())
{
    $className = str_replace('_', '\\', $className);
    /* Default helper class for a module */
    if (strpos($className, '\Helper\\') === false) {
        $className .= '\Helper\Data';
    }

    $helper = $this->_objectManager->get($className, $arguments);

    if (false === ($helper instanceof \Magento\Core\Helper\AbstractHelper)) {
        throw new \LogicException(
            $className . ' doesn\'t extends Magento\App\Helper'
        );
    }

    return $helper;
}

如果您自己实现,似乎Magento内核正在以以下两种方式之一加载它:

建立自己的工厂:

$objectManager = \Magento\Core\Model\ObjectManager::getInstance();

$helperFactory = $objectManager->get('\Magento\Core\Model\Factory\Helper');
$helper = $helperFactory->get('\PulseStorm\Commercebug\Helper\Data');

或者直接抓取它:

$helper = \Magento\Core\Model\ObjectManager::getInstance()->get('Magento\Core\Helper\Data');

1
+1获取有用的信息,但是您想直接实例化工厂吗?还是应该使用Object Manager将单个帮助程序工厂实例化为具有以下内容的缓存类get
艾伦·风暴

尚不完全清楚,因为辅助工厂是从\ Mage \ Core \ Block \ Abstract继承的-我认为其目的是提供您自己的辅助工厂。不过,看起来他们并不是故意为工厂创建单例。
philwinkle

听起来我需要/最好的消息来源是跟踪_helperFactory如何注入到这些对象中,并查看核心团队如何实例化它。
艾伦·风暴

我的简化摘要不正确,并且构造函数需要ObjectManager的实例。我会暂时编辑。
philwinkle

参见编辑。它应该可以工作-目前很难确定,因为我的cli shell环境未按预期加载store config实例。不过,这应该足以使您走上正确的道路。
philwinkle

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.