JavaScript print_r
Prints out or returns information about the specified variable
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 5556 57 58 59 6061 62 63 64 6566 67 68 69 7071 72 73 74 7576 77 78 79 | function print_r (array, return_val) { // Prints out or returns information about the specified variable // // version: 909.322 // discuss at: http://phpjs.org/functions/print_r // + original by: Michael White (http://getsprink.com) // + improved by: Ben Bryan // + input by: Brett Zamir (http://brett-zamir.me) // + improved by: Brett Zamir (http://brett-zamir.me) // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // - depends on: echo // * example 1: print_r(1, true); // * returns 1: 1 var output = "", pad_char = " ", pad_val = 4, d = this.window.document; var getFuncName = function (fn) { var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn); if (!name) { return '(Anonymous)'; } return name[1]; }; var repeat_char = function (len, pad_char) { var str = ""; for (var i=0; i < len; i++) { str += pad_char; } return str; }; var formatArray = function (obj, cur_depth, pad_val, pad_char) { if (cur_depth > 0) { cur_depth++; } var base_pad = repeat_char(pad_val*cur_depth, pad_char); var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char); var str = ""; if (typeof obj === 'object' && obj !== null && obj.constructor && getFuncName(obj.constructor) !== 'PHPJS_Resource') { str += "Array\n" + base_pad + "(\n"; for (var key in obj) { if (obj[key] instanceof Array) { str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char); } else { str += thick_pad + "["+key+"] => " + obj[key] + "\n"; } } str += base_pad + ")\n"; } else if (obj === null || obj === undefined) { str = ''; } else { // for our "resource" class str = obj.toString(); } return str; }; output = formatArray(array, 0, pad_val, pad_char); if (return_val !== true) { if (d.body) { this.echo(output); } else { try { d = XULDocument; // We're in XUL, so appending as plain text won't work; trigger an error out of XUL this.echo('<pre xmlns="http://www.w3.org/1999/xhtml" style="white-space:pre;">'+output+'</pre>'); } catch (e) { this.echo(output); // Outputting as plain text may work in some plain XML } } return true; } else { return output; } } |
Examples
Running
1 | print_r(1, true); |
Should return
1 | 1 |
Dependencies
In order to use this function, you also need:
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have print_r goodness in JavaScript.
This code works great for printing out variable information but do you think it would be possible to print out a javascript object? I am new to javascript objects otherwise I would do it myself. To be honest, I'm not even sure it is possible.
@ alexandre: I think your words are very clear :) Thanks alexandre, it's nice of you to let us know. Happy NYE tonight!
no words are able to tell how wonderful is your work. Congratulations you all!!!
PS: Sorry about my awful English... I'm Brazillian
@ nikdo: regular for loops won't work for associative arrays (js objects) so we really need these 'for key in array' structures. What version of ie are you using? I find it hard to believe that IE in general does not support these kind of loops at all, because that would have led to problems earlier on.
using for(var a in b) isnt a good idea as it doesnt work in ie and is replacable with regular for(e1;e2;e3)
May be need change:
1 | if (obj[key] instanceof Array) { |
Change to:
1 | if (obj[key] instanceof Array || obj[key] instanceof Object) { |
therefor print a nested objects
@ Francois: The bug was in the htmlspecialchars_decode function and has been fixed. Sorry for the inconvenience and thank you for tipping me!
There is a missing coma (,) at line 2985
it is:
= string.replace(/>/g '>');
but we should read:
= string.replace(/>/g, '>');
@aron budinszky: Thank you very much for your input.
The object vs array story is because PHP does not differentiate between numerically indexed arrays and 'associative arrays'. But as soon as JavaScript encounters an associative array, it becomes an 'Object'. This is an essential difference between JS & PHP. In this project we've chosen to side with PHP.
Hopefully this answers your question. As for the BR tag, if I output PHP's print_r I can choose to enclose it between PRE tags. I would like JS scripters to be able to approach JS's print_r in the same manner.
also, changing the newlines to <br> and the pad_char to " " creates a more readable result, even if it deviates from the php norm. since print_r is normally used to visually represent data, and since javascript is typically run within a browser, this might be the preferred way in this case...of course the opposite can also be argued...
oops. there was a mistake in my code below. here's the improved version...(using ben bryan's code). but i noticed that the line 6:
if (obj[key] instanceof Array || obj[key] instanceof Object)
is omitted from the current version in php.js, even though it is included in ben bryan's posted version...
1 2 3 4 56 7 8 9 1011 12 13 14 15 | if (obj instanceof Array || obj instanceof Object) { if(obj instanceof Array) name = "Array"; else name = "Object"; str += name+"\n" + base_pad + "(\n"; for (var key in obj) { if (obj[key] instanceof Array || obj[key] instanceof Object) { str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char); } else { str += thick_pad + "["+key+"] => " + obj[key] + "\n"; } } str += base_pad + ")\n"; } else { str = obj.toString(); }; |
here's a bit of an improvement for the print_r function (which, as it seems, ben bryan has partially posted below) to process nested objects as well as arrays. in addition to his code, it is important to print OBJECT or to print ARRAY for the appropriate data type, since accessing the data requires slightly different syntax.
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 55 | // {{{ print_r function print_r( array, return_val ) { // Prints human-readable information about a variable // // + discuss at: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_print_r/ // + version: 803.612 // + original by: Michael White (http://crestidg.com) // * example 1: print_r(['Kevin', 'van', 'Zonneveld']); // * returns 1: true var output = "", pad_char = " ", pad_val = 4; var formatArray = function (obj, cur_depth, pad_val, pad_char) { if(cur_depth > 0) cur_depth++; var base_pad = repeat_char(pad_val*cur_depth, pad_char); var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char); var str = ""; var name = ""; if(obj instanceof Array || obj instanceof Object) { if(obj instanceof Array) name = "Array"; else name = "Object"; str += name+"\n" + base_pad + "(\n"; for(var key in obj) { if(obj[key] instanceof Array || obj instanceof Object) { str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char); } else { str += thick_pad + "["+key+"] => " + obj[key] + "\n"; } } str += base_pad + ")\n"; } else { str = obj.toString(); }; return str; }; var repeat_char = function (len, char) { var str = ""; for(var i=0; i < len; i++) { str += char; }; return str; }; output = formatArray(array, 0, pad_val, pad_char); if(return_val !== true) { document.write("<pre>" + output + "</pre>"); return true; } else { return output; } }// }}} |
@ vinnieboombots: Looking at the code, I cannot establish how that could have happened at the moment. Would you be able to provide more debug info? (maybe a codeblock with how you tried to run print_r exactly?) Thank you.
used it on an array of all links on this page (firebug)
it replaced the page contents with a comma separated value string of the array's values.
ie: http://kevin.vanzonneveld.net/techblog,http://kevin.vanzonneveld.net/techblog,http://kevin.vanzonneveld.net/techblog,http://kevin.vanzonneveld.net/techblog,http://kevin.vanzonneveld.net/techblog,http://kevin.vanzonneveld.net/techblog
Php's print_r output is different (& better)
array
[0]=>http://kevin.vanzonneveld.net/techblog
[1]=>http://kevin.vanzonneveld.net/links
[2]=>http://kevin.vanzonneveld.net/code
[3]=>http://kevin.vanzonneveld.net/about
Where formatArray function is testing data types, it does not except types of Object, replacing the if statement with the following seems to overcome this. Basically letting OBject types be processed. Tested with FF.
1 2 3 4 56 7 8 9 1011 12 13 | if (obj instanceof Array || obj instanceof Object) { str += "Array\n" + base_pad + "(\n"; for (var key in obj) { if (obj[key] instanceof Array || obj[key] instanceof Object) { str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char); } else { str += thick_pad + "["+key+"] => " + obj[key] + "\n"; } } str += base_pad + ")\n"; } else { str = obj.toString(); }; |
@ Günter Kits: I do not agree. When the return parameter is not true, the function should not return the string but print it instead. Unless I'm overlooking something, that's what it does now?
Found a bug in print_r()
So far this bug only seems to affect Netscape and the version I am using is 7.2
Replace this segment:
1
2
3
4
5 | var repeat_char = function (len, char) { var str = ""; for(var i=0; i < len; i++) { str += char; }; return str; }; |
with this segment:
1
2
3
4
5 | var repeat_char = function (len, pad_char) { var str = ""; for(var i=0; i < len; i++) { str += pad_char; }; return str; }; |
Netscape thinks that "char" is a reserved word and so cannot be used as a variable name. It errors out saying something about a formal parameter. Changing the 'char" variable to "pad_char" solves that quite easily.
http://crestidg.com
Greats Work!!
Very, very, very thanks you!!!
All my cordial greetings and appreciation from Chile
Ricardo
avalos.ricardo@gmail.com
Hi Kevin! I post here the array_reduce function:
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 | function array_reduce(a_input, callback) { var lon = a_input.length; var res = 0; var tmp = new Array(); for(i = 0; i < lon; i += 2) { tmp[0] = a_input[i]; if(a_input[i+1]) tmp[1] = a_input[i+1]; else tmp[1] = 0; res += callback.apply(null, tmp); tmp = new Array(); } return res; } |
Usage example:
1 | array_reduce([1,2,3,4,5], function (x, y) { return (x+y); }); |
Regards!
Alfonso Jiménez (http://www.alfonsojimenez.com)


Brett Zamir
3 Feb '09