Пользовательские события наблюдателя
-
16-10-2019 - |
Вопрос
Я создал интеграцию API со сторонним розничным продавцом. Я создал свой собственный Mage::dispatchEvent
звонит до и после общения. Я в основном использую их для режима регистрации/отладки, но теперь у меня есть возможность использовать их для манипулирования данными из другого, слабо связанного модуля, который также использовал бы этот API.
В приведенном ниже примере можно манипулировать $post_string
В этом локальном объеме, основанном на том, что может сделать мой наблюдатель?
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));
Решение
Если $post_string
это строка, тогда нет. Изменения, сделанные для него в классе наблюдателя, не будут показаны в этом объеме, поскольку строки не передаются ссылкой на функции.
Есть несколько решений для этого:
Быстро, но не рекомендуется:
PHP действительно дает вам обходной путь, заставляя строку передаваться ссылкой на функцию, добавив &
Перед именем переменной, как так:
Mage::dispatchEvent('my_api_delete_before', array('post_string'=>&$post_string, 'my_cart'=>$this));
Но причина, по которой это не рекомендуется, как @dedmeet сказал в его комментарий:
Использование времени вызовов прохождения за счет не поддерживается с момента PHP версии 5.4.0
Прямо из PHP Руководство:
Примечание: Нет справочного знака на вызове функции - только по определениям функций. Определения функций только достаточно, чтобы правильно передать аргумент посредством ссылки. По состоянию на Php 5.3.0 вы получите предупреждение о том, что «проход времени звонка» устарел, когда вы используете и в Foo (& $ a);. И по состоянию на PHP 5.4.0, проход времени вызовов был удален, поэтому использование его вызовет фатальную ошибку.
Итак, вот как это сделать так, как это
Чище и рекомендуется:
Лучшим решением было бы создать Varien_Object
Потому что классы всегда передаются ссылкой. И любой класс, который распространяется Varien_Object
и Varien_Object
Сам дает вам возможность использовать Getters и Setters, которые вы найдете в 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');
Итак, чтобы реализовать Varien_object
В примере ОП:
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));
}
}