Pretty Backtrace / Stack Trace

In app/code/core/Mage/Core/functions.php Magento offers a function named mageDebugBacktrace() which is nice, but I thought could be made nicer. This backtrace shows frame numbers, file names and line numbers, classes, methods and arguments where possible. It can be placed anywhere you fancy, as long as it is included by Magento - I normally add it to functions.php when needed, and remove when I'm done.

Example output:

[ 0] app/code/core/Enterprise/Search/Model/Adapter/Abstract.php:414          Enterprise_Search_Model_Adapter_HttpStream->_search('art', Array)
[ 1] app/code/core/Enterprise/Search/Model/Resource/Engine.php:113           Enterprise_Search_Model_Adapter_Abstract->getIdsByQuery('art', Array)
[ 2] app/code/core/Enterprise/Search/Model/Resource/Collection.php:352       Enterprise_Search_Model_Resource_Engine->getIdsByQuery('art', Array)
[ 3] app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php:825         Enterprise_Search_Model_Resource_Collection->_beforeLoad()
[ 4] app/code/core/Mage/Review/Model/Observer.php:78                         Mage_Eav_Model_Entity_Collection_Abstract->load()
[ 5] app/code/core/Mage/Core/Model/App.php:1299                              Mage_Review_Model_Observer->catalogBlockProductCollectionBeforeToHtml(Varien_Event_Observer)
[ 6] app/code/core/Mage/Core/Model/App.php:1274                              Mage_Core_Model_App->_callObserverMethod(Mage_Review_Model_Observer, 'catalogBlockProductCollectionBeforeToHtml', Varien_Event_Observer)
[ 7] app/Mage.php:416                                                        Mage_Core_Model_App->dispatchEvent('catalog_block_product_list_collection', Array)
[ 8] app/code/core/Mage/Catalog/Block/Product/List.php:163                   Mage::dispatchEvent('catalog_block_product_list_collection', Array)
[ 9] app/code/core/Mage/Core/Block/Abstract.php:802                          Mage_Catalog_Block_Product_List->_beforeToHtml()
[10] app/code/core/Mage/Core/Block/Abstract.php:570                          Mage_Core_Block_Abstract->toHtml()
[11] app/code/core/Mage/Core/Block/Abstract.php:514                          Mage_Core_Block_Abstract->_getChildHtml('search_result_list', '1')

(and so on...)

Code:

function niceDebugBacktrace()
{
    $d = debug_backtrace();
    array_shift($d);
    $out = '';
    $c1width = strlen(count($d) + 1);
    $c2width = 0;
    foreach ($d as &$f) {
        if (!isset($f['file'])) $f['file'] = '';
        if (!isset($f['line'])) $f['line'] = '';
        if (!isset($f['class'])) $f['class'] = '';
        if (!isset($f['type'])) $f['type'] = '';
        $f['file_rel'] = str_replace(BP . DS, '', $f['file']);
        $thisLen = strlen($f['file_rel'] . ':' . $f['line']);
        if ($c2width < $thisLen) $c2width = $thisLen;
    }
    foreach ($d as $i => $f) {
        $args = '';
        if (isset($f['args'])) {
            $args = array();
            foreach ($f['args'] as $arg) {
                if (is_object($arg)) {
                    $str = get_class($arg);
                } elseif (is_array($arg)) {
                    $str = 'Array';
                } elseif (is_numeric($arg)) {
                    $str = $arg;
                } else {
                    $str = "'$arg'";
                }
                $args[] = $str;
            }
            $args = implode(', ', $args);
        }
        $out .= sprintf(
            "[%{$c1width}s] %-{$c2width}s %s%s%s(%s)\n",
            $i,
            $f['file_rel'] . ':' . $f['line'],
            $f['class'],
            $f['type'],
            $f['function'],
            $args
        );
    }
    return $out;
}

Usage:

echo niceDebugBacktrace();

Mike Whitby Almost 12 years ago