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