题
我已经与第三方零售商创建了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));
由于PHP版本5.4.0,因此不支持使用呼叫时间传递。
直接来自 PHP手册:
笔记: 函数调用上没有参考符号 - 仅在函数定义上。仅函数定义就足以通过参考正确地传递参数。截至5.3.0 php,您将收到警告,说您使用&在foo(&$ a);中时会弃用“逐个通行时间”。从php 5.4.0 php,逐渐通过引用删除,因此使用它会引起致命错误。
所以这是如何以一种方式做
清洁和建议:
一个更好的解决方案是创建一个 Varien_Object
因为课程总是通过引用传递。以及任何扩展的班级 Varien_Object
和 Varien_Object
本身,可以使您能够使用围绕曼根托发现的Getters和Setters。
$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
在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));
}
}