Моментальні помічники в Magento 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()

Він існує лише для серіалізації / десеріалізації.


не використовуйте статичні, оскільки це не може бути протестовано з PHP-модулем, і так, це не рекомендується. Усі залежності M2 виконуються через конструктор та керуються внутрішнім менеджером об'єктів, і отримують його як Singleton. Також не використовуйте _ для позначення видимості властивості, усі імена M2 повинні використовувати камеру
— PartySoft

@Anton Kril, якщо ми використовуємо helperв шаблоні, як-от $this->helper('Magento\Catalog\Helper\Image'), це дотримується кращої практики?
— Khoa TruongDinh

2
Ні, це не є. Шаблони повинні містити лише опорні блоки. Помічників слід уникати
— Антон Криль

10

Схоже, спонукаючі люди Магенто використовувати свою нову систему автоматичного введення залежності, щоб за допомогою конструктора об'єкта потрапляти помічники та моделі в об’єкти.

Коротка версія? Якщо у вас є об'єкт, призначений менеджером об'єктів, і прикрасите конструктор PHPDoc@param , а параметри мають відповідний набір підказки типу, менеджер об'єктів автоматично інстанціює помічник (або, я вважаю, інші об’єкти) для вас.

Наприклад, наступний конструктор вводить в об’єкт асистента основних даних.

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

Це правильна відповідь - чудове снування; не було для мене абсолютно очевидним навіть після багатого копання.
— philwinkle

2
Гаразд ... зараз мені болить голова ... сильно. Ви маєте на увазі, що ми повинні використовувати PHPDoc для "написання" коду? Це безумство. Я йду.
— Маріус

@Marius hahaha це не так вже й рідко - в блозі Алана це пояснюється певною мірою.
— philwinkle

3
@philwinkle. Я прочитав його статтю. Дуже цікаво, але я все одно кажу, що це безумство. Називайте мене старомодним, але код «назад у мої дні» був кодом, а коментарі - це ті речі, про які майже ніхто не заважав писати.
— Маріус

О ... і до речі. +1. Гарне запитання та приємна відповідь.
— Маріус

7

Крім усіх вищезазначених відповідей, якщо вам потрібно використовувати помічник у шаблоні phtml, ви можете просто так:

$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 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 core завантажує його одним із двох способів:

Згорніть власну фабрику:

$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 для корисної інформації, але ви хочете створити завод безпосередньо таким чином? Або має бути створена одна фабрика помічників з диспетчером об’єктів як клас кешування get?
— Алан Шторм

Це не зовсім зрозуміло, адже фабрика помічників успадкована від \ Mage \ Core \ Block \ Abstract - я думаю, що наміром є власний завод помічників. Це НЕ виглядати , як ніби вони навмисно створюючи Сінглтон для заводу, хоча.
— philwinkle

Здається, що мені потрібно / найкраще джерело - простежити, як _helperFactory вводиться в ці об’єкти, і побачити, як основна команда створює його.
— Алан Шторм

Мій підсумок спрощення невірний, тому що конструктор вимагає екземпляр ObjectManager. Я редагую на мить.
— philwinkle

Див. Редагування. Це повинно працювати - важко визначити в цей момент, оскільки середовище моєї клітинки оболонки не завантажує екземпляр конфігурації магазину, як очікувалося. Цього має бути достатньо, щоб ви прийшли на правильний шлях.
— philwinkle

0

Спробуйте таким чином

$helper = \Magento\Framework\App\ObjectManager::getInstance()->get('Xx\Xx\Helper\Xx');

Використання Менеджера об'єктів безпосередньо не рекомендується.
— sv3n

@ sv3n, будь ласка, поясніть, в чому причина? Спасибі.
— Такимхан

1
Краще використовувати ін'єкції залежності, а не ... відповів тут, наприклад ... magento.stackexchange.com/questions/142352/…
— sv3n
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.