Domanda

Ho creato un'integrazione API con un rivenditore di terze parti. Ho creato il mio chiamate Mage::dispatchEvent prima e dopo la comunicazione. Io per lo più utilizzare questi per la modalità di debug logging /, ma ora ho l'opportunità di usarle per manipolare i dati da un altro, modulo vagamente correlato che sarebbe anche utilizzare questa API.

In seguito ad esempio è possibile manipolare $post_string in questo ambito locale sulla base di ciò che il mio osservatore può fare?

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));
È stato utile?

Soluzione

Se $post_string è una stringa, allora no. Modifiche apportate ad esso nella classe osservatore non sarebbero stati mostrati in questo ambito perché le stringhe non sono passati per riferimento alle funzioni.

Ci sono diverse soluzioni per questo:

rapida ma non è raccomandato:

PHP ti dà una soluzione, forzando la stringa da passare con riferimento alla funzione aggiungendo un & prima del nome della variabile, in questo modo:

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

Ma la ragione per cui questo non è consigliabile, come @dedmeet ha detto nel suo commento :

utilizzando una chiamata in tempo passaggio per riferimento non è supportato dalla versione PHP 5.4.0

Direttamente dalla PHP manuale :

Nota: Non v'è alcun segno di riferimento in una chiamata di funzione - solo sulla funzione definizioni. definizioni di funzioni da soli sono sufficienti per passare correttamente l'argomento per riferimento. Dal PHP 5.3.0, si otterrà un messaggio di avviso dicendo che "call-passatempo per riferimento" è deprecato quando si usa & a foo (& $ a) ;. E come di PHP 5.4.0, call-passatempo per riferimento era rimosso, in modo da utilizzare lo solleverà un errore fatale.

Così qui è come farlo in un modo che è

Cleaner e raccomandato:

Una soluzione migliore sarebbe quella di creare un Varien_Object perché le classi sono sempre passati per riferimento. E ogni classe che estende Varien_Object e Varien_Object stesso, ti dà la possibilità di utilizzare i getter e setter a trovare in giro 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');    

Quindi, per attuare la Varien_object nell'esempio del PO:

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));
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top