Instanciation des aides dans Magento 2


26

Les dernières versions de Magento 2 ont supprimé la Mageclasse. Cela signifie que nous avons perdu la Mage::helperméthode.

Existe-t-il une technique de remplacement (usine d'assistance?) Pour instancier des assistants dans Magento 2? Ou devons-nous utiliser la nouvelle classe du gestionnaire d'objets et instancier simplement l'aide en tant qu'objet singleton / mis en cache avec get(vs. create)

Réponses:


31

Je vois que vous êtes venu à la bonne solution, je veux juste résumer.

L'injection de constructeur doit être utilisée pour récupérer l'aide (ou toute autre instance) dans la classe dont vous avez besoin:

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

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

Notez qu'aucun commentaire phpDoc n'est requis , Magento lira directement la signature du constructeur pour déterminer les dépendances requises.

\ Magento \ Core \ Helper \ Factory ne doit être utilisé que dans les rares cas où vous devez appeler plusieurs assistants ou si vous ne savez pas exactement lequel vous avez besoin.

L'utilisation directe d'Object Manager est strictement déconseillée . Veuillez donc éviter d'utiliser:

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

Il n'est là que pour la sérialisation / désérialisation.


n'utilisez pas l'électricité statique car elle ne peut pas être testée avec l'unité PHP et oui, elle est déconseillée. Toutes les dépendances M2 sont effectuées via le constructeur, et gérées par le gestionnaire d'objets en interne, et le récupéreront en tant que Singleton.N'utilisez pas non plus _ pour indiquer une visibilité de la propriété.Toutes les dénominations M2 doivent utiliser le camecase
PartySoft

@Anton Kril si nous utilisons helperdans le modèle, comme $this->helper('Magento\Catalog\Helper\Image'), il suit la meilleure pratique?
Khoa TruongDinh

2
Non. Les modèles ne doivent référencer que des blocs. Les aides doivent être évitées
Anton Kril

10

Il semble que Magento encourage les gens à utiliser leur nouveau système d'injection automatique de dépendances pour obtenir des assistants et des modèles dans des objets via le constructeur de l'objet.

La version courte? Si vous avez un objet qui est instancié par le gestionnaire d'objets, et décorer un constructeur avec un PHPDoc@param , et les paramètres a un ensemble d'indices de type approprié, le gestionnaire d'objets automatiquement instancier l'aide (ou, je crois, d' autres objets) pour vous.

Par exemple, le constructeur suivant injecterait un assistant de données de base dans l'objet.

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

Ceci est la bonne réponse - un grand détective; n'était pas totalement évident pour moi, même après beaucoup de fouilles.
philwinkle

2
OK ... maintenant ma tête me fait mal ... beaucoup. Vous voulez dire que nous sommes censés utiliser PHPDoc pour "écrire" du code? C'est de la folie. J'arrête.
Marius

@Marius hahaha ce n'est pas si rare - le blog d'Alan l'explique dans une certaine mesure.
philwinkle

3
@philwinkle. J'ai lu son article. Très intéressant, mais je dis toujours que c'est de la folie. Appelez-moi à l'ancienne, mais le code "de mes jours" était du code et les commentaires étaient ces choses que presque personne ne se donnait la peine d'écrire.
Marius

Oh, et au fait. +1. Bonne question et belle réponse.
Marius

7

En plus de toutes les réponses ci-dessus, si vous devez utiliser helper dans le modèle phtml, vous pouvez simplement faire comme ceci:

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

J'espère que c'est utile si quelqu'un ne le savait pas auparavant;)


6

La façon dont les assistants sont instanciés (au moins pour le nouveau module Backend (~ dev50)) se fait via une helperFactory:

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

Ce qui est essentiellement juste un type spécialisé d'une usine de modèles. Par exemple: Magento \ Core \ Block \ Context line 143 (dev50) dans le cadre du constructeur:

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

La fabrique d'assistance renvoie le modèle demandé en fonction du nom de la classe et s'assure qu'il s'agit d'une instanceofclasse abstraite d'assistance:

/**
 * 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;
}

Si vous deviez l'implémenter vous-même, il semble que le noyau Magento le charge de l'une des deux manières suivantes:

Roulez votre propre usine:

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

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

Ou saisissez-le directement:

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

1
+1 pour des informations utiles, mais voudriez-vous instancier directement l'usine comme ça? Ou doit-on instancier une seule fabrique d'aide avec le gestionnaire d'objets en tant que classe mise en cache avec get?
Alan Storm

Ce n'est pas totalement clair, car la fabrique d'aide est héritée de \ Mage \ Core \ Block \ Abstract - je pense que l'intention est de fournir votre propre fabrique d'aide. Cependant, il ne semble pas qu'ils créent intentionnellement un singleton pour l'usine.
philwinkle

On dirait que j'ai besoin / la meilleure source est de tracer la façon dont _helperFactory est injecté dans ces objets et de voir comment l'équipe principale l'instancie.
Alan Storm

Mon résumé de simplification est incorrect ainsi que le constructeur nécessite une instance d'ObjectManager. Je vais modifier momentanément.
philwinkle

Voir modifier. Cela devrait fonctionner - difficile à déterminer pour le moment car mon environnement shell cli ne charge pas l'instance de configuration de magasin comme prévu. Cela devrait cependant suffire à vous mettre sur la bonne voie.
philwinkle

0

Essayez de cette façon

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

L'utilisation directe d'Object Manager est strictement déconseillée.
sv3n

@ sv3n pourriez-vous s'il vous plaît expliquer, quelle est la raison?. Merci.
Thushan

1
Mieux utiliser les injections de dépendance à la place ... répondu ici par exemple ... magento.stackexchange.com/questions/142352/…
sv3n
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.