我有一个扩展,它使用该catalog_product_after_save
事件对产品和自定义导出的属性进行简单索引。
似乎在某些情况下,如果在没有所有产品数据的情况下调度此事件,那么当更新索引时,它会丢失数据。我已经进行了检查,以查找缺少的一些必需信息,因此我相信这将不再是问题,但我想记录它何时发生以及它来自何处。
那么,有什么方法可以本地确定事件是从哪里分派的,我可以在观察者中查看?
熟悉 PHP 的回溯函数(debug_backtrace
和debug_print_backtrace
)或更好的是 Magento/大对象安全版本,mageDebugBacktrace
.
例如,我为controller_action_predispatch
事件设置了一个观察者。exit
如果我将以下内容放在我的观察者中(因为观察者可能会被调用两次,对于您的具体情况,您可能不想这样做)
class Pulsestorm_Requestset_Model_Observer
{
public function myMethod($observer)
{
mageDebugBacktrace();
exit;
}
}
然后加载页面,当我尝试加载系统中的任何页面时,我将得到以下输出(因为该事件几乎在每个页面上都会触发)
[1] /magento/app/code/core/Mage/Core/Model/App.php:1343
[2] /magento/app/code/core/Mage/Core/Model/App.php:1322
[3] /magento/app/Mage.php:455
[4] /magento/app/code/core/Mage/Core/Controller/Varien/Action.php:530
[5] /magento/app/code/core/Mage/Core/Controller/Front/Action.php:64
[6] /magento/app/code/core/Mage/Core/Controller/Varien/Action.php:408
[7] /magento/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php:251
[8] /magento/app/code/core/Mage/Core/Controller/Varien/Front.php:176
[9] /magento/app/code/core/Mage/Core/Model/App.php:352
[10] /magento/app/Mage.php:691
[11] /magento/index.php:87
这为我提供了简化的调用堆栈,直到我调用mageDebugBacktrace
. 这[#]
只是一个列表排序,后跟一个:
分隔字符串。字符串( )的左侧是一个 PHP 文件,字符串( )/magento/app/code/core/Mage/Core/Model/App.php
的右侧是方法调用发生的行号。1343
前三个电话
[1] /magento/app/code/core/Mage/Core/Model/App.php:1343
[2] /magento/app/code/core/Mage/Core/Model/App.php:1322
[3] /magento/app/Mage.php:455
是分派事件本身的 PHP 代码。例如,Mage.php
我系统上的第 455 行是
$result = self::app()->dispatchEvent($name, $data);
它是(通常取决于 Magento 版本/核心状态)堆栈中的第四个调用,它将指向事件被调度的位置。
[4] /magento/app/code/core/Mage/Core/Controller/Varien/Action.php:530
我系统上的线530
是Action.php
Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $this));
答对了! Mage::dispatchEvent
是调度事件的代码,所以我们找到了我们的调度点。
如前所述,您的观察者可能会被多次调用——因此使用输出缓冲记录数据可能比上面使用的输出/退出更好
ob_start();
mageDebugBacktrace();
$contents = ob_get_clean();
Mage::Log($contents);
#If `Mage::log` is failing early in the bootstrap process
#file_put_contents('/tmp/trace.log', $contents . "\n",FILE_APPEND);
这是 mageDebugBacktrace 函数定义:
函数 mageDebugBacktrace($return=false, $html=true, $showFirst=false)
所以在研究之后,艾伦的例子可以简化成这样:
$trace = mageDebugBacktrace(true, false);
Mage::log($trace, null, 'log-name', true);
我知道的最简单的方法是做日志。在 app/Mage.php 找到这个函数
public static function dispatchEvent($name, array $data = array())
{
然后添加这些行
Mage::log($name, null, 'event_check.log', true);
比功能看起来像。
public static function dispatchEvent($name, array $data = array())
{
Mage::log($name, null, 'event_check.log', true);
Varien_Profiler::start('DISPATCH EVENT:'.$name);
$result = self::app()->dispatchEvent($name, $data);
#$result = self::registry('events')->dispatch($name, $data);
Varien_Profiler::stop('DISPATCH EVENT:'.$name);
return $result;
}
通过这样做,您可以跟踪每个正在调度的事件。