Question

J'ai créé une intégration API avec un détaillant tiers. J'ai créé mes propres appels Mage::dispatchEvent avant et après la communication. J'utilise surtout ces derniers pour le mode enregistrement / debug, mais j'ai maintenant la possibilité de les utiliser pour manipuler les données d'une autre, le module vaguement lié qui utiliseraient également cette API.

Dans le exemple ci-dessous est-il possible de manipuler $post_string dans ce champ local basé sur ce que mon observateur peut faire?

Mage::dispatchEvent('my_api_delete_before', array('post_string'=>$post_string, 'my_cart'=>$this));

$result = $this->doApiCommunication($post_string);

Mage::dispatchEvent('my_api_delete_after', array('post_string'=>$post_string, 'result'=>$result, 'product'=>$product, 'cart_item_id'=>$_item->cartItemId));
Était-ce utile?

La solution

Si $post_string est une chaîne, alors non. Les changements effectués à dans la classe d'observateurs ne seraient pas présentés dans ce champ parce que les chaînes ne sont pas passés par référence aux fonctions.

Il existe plusieurs solutions pour cela:

rapide mais pas recommandé:

PHP ne vous donne une solution de contournement, en forçant la chaîne à passer par référence à la fonction en ajoutant un & avant le nom de la variable, comme suit:

Mage::dispatchEvent('my_api_delete_before', array('post_string'=>&$post_string, 'my_cart'=>$this));

Mais la raison n'est pas recommandé, comme @dedmeet a dit dans son commentaire :

  

à l'aide du temps d'appel passe par référence est pas pris en charge depuis la version PHP 5.4.0

Directement à partir du manuel PHP :

  

Remarque: Il n'y a aucun signe de référence sur un appel de fonction - uniquement sur la fonction   Définitions. Les définitions de fonction sont les seuls suffisante pour passer correctement   l'argument par référence. PHP 5.3.0, vous obtiendrez un avertissement   en disant que « passage par référence temps d'appel » est dépréciée lorsque vous utilisez &   dans foo (& $ a) ;. Et à partir de PHP 5.4.0, passe par référence temps d'appel était   retiré, afin de l'utiliser soulèvera une erreur fatale.

Voici donc comment le faire d'une manière qui est

Cleaner et recommandé:

Une meilleure solution serait de créer une Varien_Object parce que les classes sont toujours passés par référence. Et toute classe qui étend Varien_Object et le Varien_Object lui-même, vous donne la possibilité d'utiliser les accesseurs que vous trouverez autour Mangento.

$obj = new Varien_Object();

// Set a value for data variable
$obj->setFoo($bar);

// The previous function is the same as the following:
// In fact, the previous function will call setData with 'foo' and $bar as its paramteres
$obj->setData('foo', $bar);

// To get the value of 'foo' you will need to call any of the following functions:
$obj->getFoo();

$obj->getData('foo');    

Donc, pour mettre en œuvre le Varien_object dans l'exemple de l'OP:

class Foo_Bar_Model_Communicator{

    public function someFunction(){
        /*
         * Assuming that $post_string is getting set here somehow
         * before the next line.
         */
        $eventData = new Varien_Data();

        $eventData->setData('post_string', $post_string);   
        $eventData->setData('cart', $this); 

        Mage::dispatchEvent('my_api_delete_before', array('event_data'=>$eventData));

        /* In this case, since we sent a Varien_Object as parameter,
         * whatever the Observer class does to the object, will be reflected
         * here as well.
         * We only need to make sure that we get the string back from the
         * Varien_Object instead of using $post_string.
         */
        $new_post_string = $eventData->getData('post_string');

        $result = $this->doApiCommunication($new_post_string);

        /*
         * We can do the same for the parameters for the next event, but it
         * wasn't part of the OP's question and it won't be needed since
         * there is no code following the dispatch event.
         *
         * However it would be a better idea to make the "before" & "after"
         * events have the same type of parameters which would be less 
         * confusing later on.
         */

        Mage::dispatchEvent('my_api_delete_after', array('post_string'=>$post_string, 'result'=>$result, 'product'=>$product, 'cart_item_id'=>$_item->cartItemId));
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top