4

我有一个扩展,它使用该catalog_product_after_save事件对产品和自定义导出的属性进行简单索引。

似乎在某些情况下,如果在没有所有产品数据的情况下调度此事件,那么当更新索引时,它会丢失数据。我已经进行了检查,以查找缺少的一些必需信息,因此我相信这将不再是问题,但我想记录它何时发生以及它来自何处。

那么,有什么方法可以本地确定事件是从哪里分派的,我可以在观察者中查看?

4

3 回答 3

11

熟悉 PHP 的回溯函数(debug_backtracedebug_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

我系统上的线530Action.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);
于 2013-04-03T19:26:32.020 回答
3

这是 mageDebugBacktrace 函数定义:

函数 mageDebugBacktrace($return=false, $html=true, $showFirst=false)

所以在研究之后,艾伦的例子可以简化成这样:

$trace = mageDebugBacktrace(true, false);
Mage::log($trace, null, 'log-name', true);
于 2013-04-04T21:30:44.573 回答
1

我知道的最简单的方法是做日志。在 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;
}

通过这样做,您可以跟踪每个正在调度的事件。

于 2013-05-19T06:06:18.173 回答