Sexy Cake with Krumo: Say Goodbye to print_r()

By Stacy Pawlowich (stac80)
Debugging nested arrays with print_r() can be wicked tough but Krumo makes this task a little less crack-a-lackin.
To put it simply, Krumo is a replacement for print_r() and var_dump(). By definition Krumo is a debugging tool (PHP4/PHP5), which displays structured information about any PHP variable.
---Some Poindexter @ http://krumo.sourceforge.net/

Installin Dat


Downlizzle and extract Krumo to your vendors directory.


Directory structure should look a little something like:

-app/

-cake/

-log/

-vendors/

--krumo/

---docs/

---skins/

---class.krumo.php

---krumo.ini

---krumo.js

---krumo.php


The krumo configamajiguration file:
Download code

; KRUMO CONFIGURATION FILE
;

[skin]
selected = "schablon.com"
;
; Change the above value to set the CSS skin used to render 
; Krumo layout. If the skin is not found, then the "default" one 
; is going to be used. Check the skins directory for options.
;

[css]
url = ""
;
; This value is used to set the URL path to 
; where the Krumo folder is. This value doesn't 
; need to be set. Works perfectly unset on my
; install.
;
vendors/krumo/krumo.ini


Helper Monkey


Warning: Geeksturbation in 3..2..1: Implementing krumo as a helper will allow us to disable krumo simply by changing our app from DEBUG level 1, 2 or 3 (development) to 0 (production) in our core config file. This way we won't have to go back through all our views and remove our krumo instances.

Helper Class:

Download code <?php 

vendor
('krumo/class.krumo');

class 
KrumoHelper extends Helper {
    
    
// enable krumo in development mode
    // disable krumo in production mode 
    // (changed 2008-06-06 as per A. Martini's
    // comment, below, regarding v1.2 warnings)
    
function __construct() {

        if(
Configure::read('debug') != 0) {

            
krumo::enable();

        } else {

            
krumo::disable();

        } 

    }

}

?>
app/views/helpers/krumo.php


Using Krumo in Your Views


First we add Krumo to our array of helpers:

Controller Class:

Download code <?php 
---EXAMPLE CONTROLLER---

class 
FooController extends AppController {

     var 
$helpers = array('Krumo');

... 
controller logic ...

}

?>
app/controllers/foo_controller.php


Next we include Krumo in our views:

View Template:

Download code <?php
---EXAMPLE VIEW---

// expands the arrays contained in the following variables:
krumo($fooVariable1);
krumo($fooVariable2);
?>

... view ...

<?php foreach($fooVariable as $foo): ?>
    
    //expands the foo variables
    krumo($foo);

... foreach loop ...

<?php endforeach; ?>

/app/views/foo/index.ctp


So how much help is Krumo? Well if you're a savant and rarely have to dump your variables to see where you're going wrong then probably not much but if you're trying to parse multidimensional arrays with a lot of text it can get tough figuring the different depths your data is at. Krumo uses css and the dom to make each layer of an array collapsible so you can browse easily...but I'm sensing doubt on your part. You still haven't seen it with your own eyes right?


CHECK IT:


Examples abound on K to the ruzzle M to the izzo's site.


Word!..erm String!

 

Comments 474

CakePHP Team Comments Author Comments
 

Comment

1 Uhh.....

Ummm.....ain'tcha got no pr() on yer system?!
Posted Jul 16, 2007 by Walker Hamilton
 

Comment

2 A more simple way.

Hi ! thanks for sharing this wonderfull tool.

I would tell you how I integrated krumo on Cake:
First replace I replace the content on /cake/libs/view/templates/elements/dump.thtml with:


Controller dump:

controller); ?>

Creating your Helper, I just place on the head of the /apps/apps_controller.php file the line:
var $helpers = array('Krumo');

And all work great, there is no more to do.

Regards and best Wishes.
Posted Jul 18, 2007 by Mario Cesar
 

Comment

3 Probably

Ummm.....ain'tcha got no pr() on yer system?!
I probably do but I'm still a nooblet in the cake arena. I like CAKE but the documentation is lacking. Definitely too much emphasis explaining the intricacies of MVC while leaving the actual usage and examples of the methods kind of vague. I realise they wanted the manual to be succinct but CAKE is a very large and complicated bit of software and I have struggled many times to locate the answers I have needed. A manual doesn't need to be ultra simple to attract users nor does it need to be written in geekistani to cover topics thoroughly. If I knew CAKE better I would offer to help.

But thanks for the pr() I checked it out and it is very helpful and basically the same thing as krumo. I think if you are dealing with large bodies of text it would still be too verbose and Krumo folds all the dimensions of your array and lets you expand them as you need them. This is great because it doesn't take a whole lot of real estate on a page or force you to page down past all the pr() output to see how the view rendered.
Posted Jul 19, 2007 by Stacy Pawlowich
 

Question

4 Skin images do not appear

[css] url = ""
;
; This value is used to set the URL path to
; where the Krumo folder is. This value doesn't
; need to be set. Works perfectly unset on my
; install.

The skin images don't appear with this setup. Any way to automate this? I've copied the skins folder into /app/webroot/krumo/skins and set the url to the base url of the project, which works, but it's a bit annoying to have to do this; I'd rather have all the krumo files in one place and have the folder autodetected.
Posted Jul 24, 2007 by JP Mortiboys
 

Comment

5 Skins and Web Accessible URL

The skin images don't appear with this setup. Any way to automate this? I've copied the skins folder into /app/webroot/krumo/skins and set the url to the base url of the project, which works, but it's a bit annoying to have to do this; I'd rather have all the krumo files in one place and have the folder autodetected.
In my setup I found no need to either move the skins into a web accessible folder nor set the url. I will admit I was expecting to have to do exactly that but it just worked. I can change the skin and I get that skin in my view so I can't say for certain why it isn't working for you. I basically assumed CAKE did it automagically. I'll try and check into that as soon as I can and see if I can figure it out.
Posted Jul 24, 2007 by Stacy Pawlowich
 

Question

6 Does not work

I'm using cakephp 1.2, I did all that you write, but when y put:

$krumo($a);

the browser show me an error:

Fatal error: Function name must be a string in ..\app\views\ps3\index.ctp on line 3
Posted Feb 6, 2008 by Yonel Meza Avila
 

Comment

7 Reply to Does not work

I'm using cakephp 1.2, I did all that you write, but when y put:

$krumo($a);

the browser show me an error:

Fatal error: Function name must be a string in ..\app\views\ps3\index.ctp on line 3

It should be:

krumo($a);

not:

$krumo($a);
Posted Feb 6, 2008 by Stacy Pawlowich
 

Comment

8 Controller dump

I frequently use the pr() function to debug. But it would be a nice addon to the controller dump when you set debug to 3. Which is extremely long.
Posted Feb 28, 2008 by David Coll
 

Comment

9 Some enhancements

Nice work! Krumo is an excellent tool, even if usually pr() is enough for most applications.

Here are 4 little enhancement I wrote hoping they can be useful for Krumo's lovers.

Recursive Fold/Unfold all


Folding and unfolding Krumo's capabilities are supposed to be used especially with very long results, hence the need to click on every single node can be very annoying. What Krumo is missing, in my opinion, is a way to fold and unfold recursively a set of nodes. I think it's unconfortable to have a dinamically structured print of a complex dump if it requires tons of clicks.

My version of Krumo displays a "++" next to each node's name: clicking on it every child node is recursively unfolded and "++" becomes "--". Equally, clicking on a "--" every child node will be folded. This may ease and speed up node's browsing.

To achieve this result, you have to change both class.krumo.php and krumo.js

In krumo.js add


krumo.toggleAll = function(el) {
    var ul = el.parentNode.parentNode.getElementsByTagName('ul');
    
    var parentMode = (ul[0].parentNode.style.display == 'none')
                ? 'block'
                : 'none';
    var parentText = (ul[0].parentNode.style.display == 'none')
                ? '--'
                : '++';
    el.innerHTML = parentText;
    for (var i=0; i<ul.length; i++) {
            ul.parentNode.style.display = parentMode;
            
    }

    var expandAlls = el.parentNode.parentNode.getElementsByClassName('expandall');
    for (var i=0; i<expandAlls.length; i++) {
        expandAlls.innerHTML = parentText;

    }

}


Other small fixes are in the resulting file wich you can download from the bottom of this page.

In krumo.php, you have to change function _array() in order to print the '++' element with the right javascript onClick event.



Private Static Function _array(&$data, $name) {
?>
<li class="krumo-child">
    <div class="krumo-element<?php echo (count($data) > 0) ? ' krumo-expand' ' krumo-dontexpand';?>"
        <?php if (count($data) > 0) {?> onClick="return;krumo.toggle(this);"<?php ?>
        >
            <a class="krumo-name" <?php if (count($data) > 0) {?> onClick="krumo.toggle(this.parentNode);"<?php ?>>
                <?php echo $name;?>
            </a> |
            <a class="expandall" <?php if (count($data) > 0) {?> onClick="krumo.toggleAll(this);"<?php ?>>
                <?php echo "++";?>
            </a>




Only clickable items showed as links


Foldable and unfoldable items always appear underlined, as ordinary links but of course, they cannot be clicked. This can be confusing. To improve readibility, I think unfoldable items should be printed as normal text. This can be easily obtained adding a css class "krumo-dontexpand" and substituting, in class.krumo.php::_string(), the code



<div class="krumo-element<?php echo $_extra ' krumo-expand' '';?>"
        <?php if ($_extra) {?> onClick="krumo.toggle(this);"<?php ?>
        onMouseOver="krumo.over(this);"
        onMouseOut="krumo.out(this);">

with


<div class="krumo-element<?php echo $_extra ' krumo-expand' ' krumo-dontexpand';?>"

Then, you can style your krumo-dontexpand items as desired. I'm using


div.krumo-dontexpand a{
    text-decoration:none;
    color:black;
    }
div.krumo-expand a{
    text-decoration:underline;
}


Fix Cake v1.2 warning


Original Krumo's helpers produces a warning with Cake v1.2, because of the use of DEBUG.

To make Krumo's helper CakePHP v1.2 compatible, just change APP/views/helpers/krumo.php from


if(DEBUG != 0) {

            krumo::enable();



        } else {

            krumo::disable();

        }
to


if(Configure::read('debug') != 0) {

            krumo::enable();



        } else {

            krumo::disable();

        }


OnMouseOver without JavaScript


The last little enhancement is for the Hover coloring effect. You can add the class



div.krumo-element:hover
{
    background-color: #aaaaff;
}

in the skin.css file and get rid of the two Javascript functions


krumo.over = function(el) {
    krumo.reclass(el, 'krumo-hover');
    }

krumo.out = function(el) {
    krumo.unclass(el, 'krumo-hover');
    }

in the file krumo.js


Hence every reference to onMouseOver() and onMouseOut() in krumo.php can be deleted. For example,


<div class="krumo-element"
        onMouseOver="krumo.over(this);"
        onMouseOut="krumo.out(this);">
        
            <a class="krumo-name"><?php echo $name;?></a>
            (<em class="krumo-type krumo-null">NULL</em>) 
    </div>

becomes


<div class="krumo-element"        
            <a class="krumo-name"><?php echo $name;?></a>
            (<em class="krumo-type krumo-null">NULL</em>) 
    </div>


Download the code


You can find the results here

[url=http://www.bebox.it/public/krumo.tar.gz]http://www.bebox.it/public/krumo.tar.gz

If you find bugs, please don't exitate to contact me.
[email=arialdomartini@bebox.it=arialdomartini@bebox.it]arialdomartini@bebox.it
Posted Jun 6, 2008 by Arialdo Martini
 

Comment

10 Nice Job

Here are 4 little enhancement I wrote hoping they can be useful for Krumo's lovers.

That's impressive, you should submit your fold/unfold enhancements upstream to krumo.

I put the v1.2 debug change you suggest into the original article. Thanks!
Posted Jun 16, 2008 by Stacy Pawlowich
 

Question

11 krumo from controllers

hello. really nice article. but as far as i understand - with this helper you can not print things from, for example, controllers, because krumo is initialized only in rendering stage. is this right?
Posted Aug 28, 2008 by Tomas Kakomas