Magento中的帮助者是什么?


Answers:


27

从理论上讲,您永远不要使用助手。
助手只是不相关方法的集合,并且总是作为单例实例化。
这基本上是过程式编程,其功能分组在某个名称空间(在本例中为类名称)下。但是由于Magento的核心是助手,因此您可以将方法放在那里,不知道将它们放在哪里,或者是否需要在许多不同的地方调用它们(模型,控制器,模板)

不得已时使用它们。

同样,由于翻译原因,Magento的每个模块都需要一个助手。
您只需Data.php在每个模块中创建一个名为的帮助程序,然后将其保留为空即可。


我为助手找到的唯一真正的“用法”是保证它们始终是单例。我研究了一些教育性的遗留代码,这些代码在foreach循环和各种疯狂中加载了集合。我发现将这种令人恐惧的逻辑分解为辅助函数,并将其用作对象缓存很有用,并且为将来可能偶然调用getModel而不是getSingleton将其放入模型中的开发人员的错误留出了很少的空间。
路德·罗杰斯

@LukeRodgers。我明白您的意思,但我认为“可能不小心调用了getModel而不是getSingleton”成为使用助手的真正原因。我可以争辩说,您可以“偶然”调用“删除”而不是“保存”。您可以采取什么保护措施来避免这种情况?我想“关注”是软件开发的一部分。
Marius

同意 在这些情况下,我想我只是在尝试防御人类的代码。
路加·罗杰斯

您将如何向核心帮助者添加自定义方法?
tecjam

13

这个问题有两个方面:

  1. 我应该自己写助手吗?
  2. 我应该使用核心助手吗?

1.写作助手

在一般情况下,具有类命名HelperUtil或类似只是说:“我有一些功能,我不知道放在哪里”,并没有多大意义的一类。

Magento将帮助程序实例化为单例,并且大多数核心帮助程序没有任何状态,因此这些方法也可以是static甚至functions没有类。所有这些通常被认为是代码异味,这是应用程序设计中的缺陷。

正如Marius所指出的那样,您不需要为自己的代码使用帮助器。如果您使用模块特定的翻译,则只需为每个模块创建一个默认的空帮助程序,否则它们将无法工作。首选模型(Mage_Core_Model_Abstract如果它们不表示数据库数据,则不需要扩展)或独立的库类。

但是,对于“根本不使用助手”,我并不太严格,而是将它们用于查询快捷方式,例如:

  • 接入模块配置:

    public function getFooBar() 
    {
        return Mage::getStoreConfig('module/foo/bar');
    }
    
  • 库类的工厂方法

    public function getNewFooService()
    {
        return new \Foo\Service(...);
    }
    

您可以找到其他地方,但是恕我直言,模块助手通常足以应付此类问题。


2.使用助手

消耗核心助手是您经常要做的事情。

例子:

  • __()翻译方法:要获取特定模块的翻译,请使用Mage::helper('module-alias')->__('string to be translated')。如果$this->__(...)在模板或块中使用并且translate="..."在XML文件中使用属性,则隐式发生
  • Mage::helper('core') 方法:本地化日期,价格和货币格式,转义和编码数据
  • Mage::helper('tax') 从税收配置中获取信息并基于此计算价格的方法
  • Mage::helper('catalog/image') 提供一个接口来创建缓存的和调整大小的目录图像并检索其URL
  • Mage::helper('catalog/product_url_rewrite')->joinTableToSelect() 将URL重写表连接到产品集合查询。

核心帮助程序中隐藏了许多(或多或少)有用的功能,如果您需要某个特定功能可能会在某个地方的核心中使用,请检查是否可以重用帮助程序方法。

通常,这些助手是无状态对象,方法是查询方法(即它们没有副作用)

但是,像往常一样,Magento违反了自己的不成文规则,因此不应作为示例。一个不使用助手的“好”示例是Mage_Catalog_Helper_Product_Compare具有$_itemCollection只能初始化一次的$_customerId属性和可以使用设置器更改的属性。您将找到更多与目录相关的帮助器,并带有附加的收藏夹。为使用它们的代码编写测试或在不同的上下文中重复使用它们并不有趣,因此请不要在家中这样做。

catalog/image上面提到的帮助程序是一个实际上不应成为帮助程序的帮助程序的另一个示例。您需要传递的产品init()首先要重置其当前状态,然后设置各种参数(例如resize()setQuality()),最后可以使用其__toString()方法获取URL 。在模板中使用时看起来不错,但是代码非常混乱,作为单例来说没有意义。


TL; DR:

  • 核心助手包含有用的工具。
  • 您需要翻译帮手
  • 助手应该是无国籍的
  • 在您自己的模块中,避免将辅助程序用作各种功能集合。在大多数情况下,您可以找到更合适的地方

我经常在基于平面文件的简单ERP集成中使用帮助程序。他们所做的只是从本地目录写入和读取文件,以及更新其他对象(产品,订单等)。在提到的实例中,它们没有自己的状态或对应的表。您对此有何看法?
musicliftsme

1
那违反了“没有副作用”。我通常会读写文件ReaderWriter模型,它们实际上确实具有状态(至少是文件资源)。例如,要从CSV文件中读取订单状态数据,我将有……。lika OrderStatusCsvReader模型所使用的OrderStatusUpdater模型。这样,我也将关注点“从文件读取数据”和“ Magento中的更新顺序”分开了
Fabian Schmengler 2015年

4

马吕斯是对的。我认为助手是胡说八道。

但是在magento理论中,您应该将一切都放入助手中,而这不会改变对象的状态,例如,获取格式化的价格。

但是您可以放入帮助程序中的所有内容,也可以放入模型中。您可以获得模型的不同实例,这对测试很有帮助。


2

我对Magento还是很陌生,但是对我来说,Helper相当于Magento的一项服务:“一组可重复用于不同目的的相关软件功能”。模块通过服务导出其提供的功能。使用帮助程序来邀请其他模块使用这些功能。

模型仅应提供与获取或设置对象状态直接相关的方法,或者以其他方式链接到模型的实例化对象的方法。


1

帮助对于防止重复的代码(在模型,模板等中)很有用,有时它们只是必需的。

  • 为了检查您的自定义模块是否已启用,可以Mage::getStoreConfigFlag('my/module/enabled')在每个要检查的文件中放置类似的内容,或者可以使用以下Mage::helper('my_module')->isEnabled()好处:
    • 如果配置路径由于某种原因而改变,您只需要调整一个文件
    • 您可以重写helpers isEnabled()方法,它将影响使用该方法的所有类,而不是重写多个文件
  • 13th @如何编写自定义扩展名?注意:除非必要,否则不要重写类。使用观察者,如果无法使用作为参数和您要覆盖的类的实例接收的帮助器方法。错误:重写Mage_Catalog_Model_Product添加方法getProductArticles()。在您的助手中添加getProductArticles(Mage_Catalog_Model_Product $product)
  • 使布局更新更灵活 <action method="someMethod"><var helper="module/method" /></action>

您只需Data.php在每个模块中创建一个名为的帮助程序,然后将其保留为空即可

使用PHPUnit时,应添加一行protected $_moduleName = 'My_Module';

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.