Вспомогательные помощники в Мадженто 2

26

Последние сборки Magento 2 покончили с Mageклассом. Это значит, что мы потеряли Mage::helperметод.

Существует ли метод замены (фабрика помощников?) Для создания экземпляров помощников в Magento 2? Или мы должны использовать новый класс диспетчера объектов и просто создать экземпляр помощника как одиночный / кэшированный объект с get(против create)

Алан Сторм
источник

Ответы:

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
@ Антон Крил, если мы используем helperв шаблоне, как $this->helper('Magento\Catalog\Helper\Image'), это следует за лучшей практикой?
Khoa TruongDinh
2
Нет. Шаблоны должны только ссылочные блоки. Следует избегать помощников
Антон Криль
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 хахаха, это не так уж редко - блог Алана объясняет это в некоторой степени.
Philwinkle
3
@philwinkle. Я прочитал его статью. Очень интересно, но я все еще говорю, что это безумие. Назовите меня старомодным, но код "в мои дни" был кодом, а комментарии были теми вещами, которые почти никто не удосужился написать.
Мариус
Ох ... и кстати. +1. Хороший вопрос и хороший ответ.
Мариус
7

Помимо всех приведенных выше ответов, если вам нужно использовать помощник в шаблоне phtml, вы можете просто сделать это так:

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

Надеюсь, будет полезно, если кто-то не знал этого раньше;)

rbncha
источник
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 line 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');
philwinkle
источник
1
+1 за полезную информацию, но вы бы хотели создать экземпляр фабрики напрямую? Или следует создать единственную вспомогательную фабрику с помощью диспетчера объектов как кэшированный класс с get?
Алан Шторм
Это не совсем понятно, потому что фабрика помощников унаследована от \ Mage \ Core \ Block \ Abstract - я думаю, что намерение состоит в том, чтобы предоставить свою собственную фабрику помощников. Это не выглядеть , как будто они намеренно создавая синглтон для завода, хотя.
Philwinkle
Похоже, мне нужно / лучший источник - это проследить, как _helperFactory внедряется в эти объекты, и посмотреть, как его реализует основная команда.
Алан Шторм
Мое упрощенное резюме неверно, так как для конструктора требуется экземпляр ObjectManager. Я буду редактировать на мгновение.
Philwinkle
Смотрите редактировать. Это должно работать - трудно определить в данный момент, потому что моя среда оболочки оболочки не загружает экземпляр конфигурации магазина, как ожидалось. Этого должно быть достаточно, чтобы вы встали на правильный путь.
Philwinkle
0

Попробуй так

$helper = \Magento\Framework\App\ObjectManager::getInstance()->get('Xx\Xx\Helper\Xx');
Thushan
источник
Использование диспетчера объектов напрямую не рекомендуется.
sv3n
@ sv3n не могли бы вы объяснить, в чем причина ?. Спасибо.
Тушан
1
Лучше использовать инъекции зависимостей вместо этого ... здесь ответили, например ... magento.stackexchange.com/questions/142352/…
sv3n