Variable handling 函数
在线手册:中文  英文

print_r

(PHP 4, PHP 5)

print_r 打印关于变量的易于理解的信息。

描述

bool print_r ( mixed $expression [, bool $return ] )

Note: 参数 return 是在 PHP 4.3.0 的时候加上的

print_r() 显示关于一个变量的易于理解的信息。如果给出的是 stringintegerfloat,将打印变量值本身。如果给出的是 array,将会按照一定格式显示键和元素。object 与数组类似。

记住, print_r() 将把数组的指针移到最后边。使用 reset() 可让指针回到开始处。

<pre>
<?php
    $a 
= array ('a' => 'apple''b' => 'banana''c' => array ('x','y','z'));
    
print_r ($a);
?>
</pre>

上边的代码将输出:

<pre>
Array
(
    [a] => apple
    [b] => banana
    [c] => Array
        (
            [0] => x
            [1] => y
            [2] => z
        )
)
</pre>

如果想捕捉 print_r() 的输出,可使用 return 参数。若此参数设为 TRUEprint_r() 将不打印结果(此为默认动作),而是返回其输出。

Example #1 return 参数示例

<?php
    $b 
= array ('m' => 'monkey''foo' => 'bar''x' => array ('x''y''z'));
    
$results print_r ($btrue); //$results 包含了 print_r 的输出结果
?>

Note: 如果想在 PHP 4.3.0 之前的版本中捕捉 print_r() 的输出,可使用输出控制函数

Note: 在 PHP 4.0.4 之前的版本中,如果给出的 arrayobject 包含了直接或间接指向自身的引用, print_r() 将永远继续下去。print_r($GLOBALS) 就是一个例子,因为 $GLOBALS 自身即是全局变量,其包含了指向自身的引用。

参见 ob_start()var_dump()var_export()


Variable handling 函数
在线手册:中文  英文

用户评论:

preda dot vlad at yahoo dot com (2013-03-22 09:40:42)

print_r(), just like var_dump() does NOT cast an object, not even if it has a __toString() method - which is normal.

<?php
class {
    public function 
__toString() {
        return 
'In class A';
    }
}
$a = new A;
echo 
$a// In class A
print_r($a); // A Object()
// you can simulate the echo by casting it manually
print_r((string)$a);  // In class A

ReanimationXP at g m a i l dot com (2012-07-22 12:49:15)

If you're like me and just want an exact version of print_r() except formatted to HTML without a bunch of bs, here you go.

The output is identical to print_r() but renders in HTML.

<?php
// Displays a multi-dimensional array as a HTML unordered lists.
function displayTree($array) {
     
$newline "<br>";
     foreach(
$array as $key => $value) {    //cycle through each item in the array as key => value pairs
         
if (is_array($value) || is_object($value)) {        //if the VALUE is an array, then
            //call it out as such, surround with brackets, and recursively call displayTree.
             
$value "Array()" $newline "(<ul>" displayTree($value) . "</ul>)" $newline;
         }
        
//if value isn't an array, it must be a string. output its' key and value.
        
$output .= "[$key] => " $value $newline;
     }
     return 
$output;
}
?>

henzeberkheij at gmail dot com (2012-01-28 15:10:31)

print_r is used for debug purposes. Yet I had some classes where I just wanted the values coming out of the database, not all the other crap. thus i wrote the following function. If your class has an toArray function, that one will be called otherwise it will return the object as is. print_neat_classes_r is the function that should be called!

<?php
print_neat_classes_r
($array$return=false){
        return 
print_r(self::neat_class_print_r($array), $return);
    }
    
function 
do_print_r($array$return=false){
        if(
is_object($array) && method_exists($array'toArray')){
            return 
$array->toArray();
        }else if(
is_array($array)){
            foreach(
$array as $key=>$obj){
                
$array[$key] = self::do_print_r($obj$return);
            }
            return 
$array;
        }else{
            return 
$array;
        }
    }
?>

eithed (2011-10-21 02:25:49)

Bear in mind that print_r actually reserves some memory to do something - so, for example thing like:

<?php
function shutdown_handler()
{
    
file_put_contents($_SERVER['DOCUMENT_ROOT']."/log.txt"print_r($_REQUESTtrue));
}

ini_set('memory_limit''1M');
register_shutdown_function("shutdown_handler");

$array = array();
while(
true)
    
$array[] = new stdClass();
?>

will just not work. Try using var_export, and presto, everything is fine.

jwood at JPL dot gov (w/ Bug fixed) (2011-08-10 16:04:10)

<?php
 
// Displays a multi-dimensional array as a HTML List (Tree structure).
function displayTree($var) {
     
$newline "\n";
     foreach(
$var as $key => $value) {
         if (
is_array($value) || is_object($value)) {
             
$value $newline "<ul>" displayTree($value) . "</ul>";
         }

         if (
is_array($var)) {
             if (!
stripos($value"<li class=")) {
                
$output .= "<li class=\"file\">" $value "</li>" $newline;
             }
             else {
                
$output .= $value $newline;
             }
         
         }
         else { 
// is_object
            
if (!stripos($value"<li class=")) {
               
$value "<ul><li class=\"file\">" $value "</li></ul>" $newline;
            } 
            
            
$output .= "<li class=\"folder\">" $key $value "</li>" $newline;
         }
         
     }
     
     return 
$output;
}
?>
 
///////////////////
 
Also need to add this to your style sheet (and get the necessary images...):
 
li.folder
 {
 list-style-image: url(../img/folder.gif);
 }
 
li.file
 {
 list-style-image: url(../img/file.gif);
 }
 
///////////////////
 
Example Usage:
 
<?php
     
...
 
    echo 
"<ul>";
     echo 
displayTree($array);
     echo 
"</ul>";
 
?>

Robert Heine (joomla-jquery-internet.de) (2011-04-18 07:09:55)

Since i use print_r for debugging a lot, i always use the following function in my scripts, which makes life a lot easier :-)

<?php
if (!function_exists("preprint")) {
    function 
preprint($s$return=false) {
        
$x "<pre>";
        
$x .= print_r($s1);
        
$x .= "</pre>";
        if (
$return) return $x;
        else print 
$x;
    }
}
?>

-------------------

USAGE:  preprint($x);   <- where $x = array(). 

-------------------

The optional 2. parameter can be set to "true", so the html-code is returned.

Have fun,

machuidel (2011-02-03 04:01:05)

The following will output an array in a PHP parsable format:

<?php
function serialize_array(&$array$root '$root'$depth 0)
{
        
$items = array();

        foreach(
$array as $key => &$value)
        {
                if(
is_array($value))
                {
                        
serialize_array($value$root '[\'' $key '\']'$depth 1);
                }
                else
                {
                        
$items[$key] = $value;
                }
        }

        if(
count($items) > 0)
        {
                echo 
$root ' = array(';

                
$prefix '';
                foreach(
$items as $key => &$value)
                {
                        echo 
$prefix '\'' $key '\' => \'' addslashes($value) . '\'';
                        
$prefix ', ';
                }

                echo 
');' "\n";
        }
}
?>

Jake Lodwick (2011-01-08 09:31:41)

This function removes clutter from print_r's output.
I use it instead of print_r now.

Here is an example:

<?PHP

$data 
= array(
    
"mode" => "sets",
    
"sets" => array(
        
123,
        
456,
        
789
    
),
    
"etc" => array(
        
"letters" => array(
            
"a",
            
"b"
        
),
        
"pie",
        
"sharks"
    
)
);

print_r($data);

/*
Array
(
    [mode] => sets
    [sets] => Array
        (
            [0] => 123
            [1] => 456
            [2] => 789
        )

    [etc] => Array
        (
            [letters] => Array
                (
                    [0] => a
                    [1] => b
                )

            [0] => pie
            [1] => sharks
        )

)
*/

neat_r($data);

/*
mode: sets
sets: 
  123
  456
  789
etc: 
  letters: 
    a
    b
  pie
  sharks

*/
?>

Here is the function:

<?PHP

/*
    neat_r works like print_r but with much less visual clutter.
    By Jake Lodwick. Copy freely.
*/
function neat_r($arr$return false) {
    
$out = array();
    
$oldtab "    ";
    
$newtab "  ";
    
    
$lines explode("\n"print_r($arrtrue));
    
    foreach (
$lines as $line) {

        
//remove numeric indexes like "[0] =>" unless the value is an array
        
if (substr($line, -5) != "Array") {    $line preg_replace("/^(\s*)\[[0-9]+\] => /""$1"$line1); }
        
        
//garbage symbols
        
foreach (array(
            
"Array"        => "",
            
"["            => "",
            
"]"            => "",
            
" =>"        => ":",
        ) as 
$old => $new) {
            
$out str_replace($old$new$out);
        }

        
//garbage lines
        
if (in_array(trim($line), array("Array""("")"""))) continue;

        
//indents
        
$indent "";
        
$indents floor((substr_count($line$oldtab) - 1) / 2);
        if (
$indents 0) { for ($i 0$i $indents$i++) { $indent .= $newtab; } }

        
$out[] = $indent trim($line);
    }

    
$out implode("\n"$out) . "\n";
    if (
$return == true) return $out;
    echo 
$out;
}

?>

Levofski (2010-05-14 05:19:53)

Hi all, here is a function that will display any variable, including objects, as XML so you can expand and collapse in browsers etc. Note that it will output all variables, not just public ones.

<?php

/**
 * Will output in a similar form to print_r, but the nodes are xml so can be collapsed in browsers
 * 
 * @param mixed $mixed 
 */
function print_r_xml($mixed)
{
    
// capture the output of print_r
    
$out print_r($mixedtrue);
    
    
// Replace the root item with a struct
    // MATCH : '<start>element<newline> ('
    
$root_pattern '/[ \t]*([a-z0-9 \t_]+)\n[ \t]*\(/i';
    
$root_replace_pattern '<struct name="root" type="\\1">';
    
$out preg_replace($root_pattern$root_replace_pattern$out1);

    
// Replace array and object items structs
    // MATCH : '[element] => <newline> ('
    
$struct_pattern '/[ \t]*\[([^\]]+)\][ \t]*\=\>[ \t]*([a-z0-9 \t_]+)\n[ \t]*\(/miU'
    
$struct_replace_pattern '<struct name="\\1" type="\\2">';
    
$out preg_replace($struct_pattern$struct_replace_pattern$out);
    
// replace ')' on its own on a new line (surrounded by whitespace is ok) with '</var>
    
$out preg_replace('/^\s*\)\s*$/m''</struct>'$out);
    
    
// Replace simple key=>values with vars
    // MATCH : '[element] => value<newline>'
    
$var_pattern '/[ \t]*\[([^\]]+)\][ \t]*\=\>[ \t]*([a-z0-9 \t_\S]+)/i';
    
$var_replace_pattern '<var name="\\1">\\2</var>';
    
$out preg_replace($var_pattern$var_replace_pattern$out);
    
    
$out =  trim($out);
    
$out='<?xml version="1.0"?><data>'.$out.'</data>';

    return 
$out;
}

?>

Alexander (2010-03-19 05:20:36)

A simple function to send the output of print_r to firebug.
The script creates a dummy console object with a log method for when firebug is disabled/not available.

<?php
function debug ($data) {
    echo 
"<script>\r\n//<![CDATA[\r\nif(!console){var console={log:function(){}}}";
    
$output    =    explode("\n"print_r($datatrue));
    foreach (
$output as $line) {
        if (
trim($line)) {
            
$line    =    addslashes($line);
            echo 
"console.log(\"{$line}\");";
        }
    }
    echo 
"\r\n//]]>\r\n</script>";
}
?>

liamtoh6 at hotmail dot com (2010-02-03 10:01:42)

I add this function to the global scope on just about every project I do, it makes reading the output of print_r() in a browser infinitely easier.

<?php
function print_r2($val){
        echo 
'<pre>';
        
print_r($val);
        echo  
'</pre>';
}
?>

It also makes sense in some cases to add an if statement to only display the output in certain scenarios, such as:

if(debug==true)
if($_SERVER['REMOTE_ADDR'] == '127.0.0.1')

jeremy dot ruten at gmail dot com (2009-09-26 19:16:03)

Here's an array_depth() function that calculates the depth of an array using the indentation in the output of print_r():

<?php

function array_depth($array) {
    
$max_indentation 1;

    
$array_str print_r($arraytrue);
    
$lines explode("\n"$array_str);

    foreach (
$lines as $line) {
        
$indentation = (strlen($line) - strlen(ltrim($line))) / 4;

        if (
$indentation $max_indentation) {
                
$max_indentation $indentation;
        }
    }

    return 
ceil(($max_indentation 1) / 2) + 1;
}

?>

It's better than writing a recursive function to do the same thing, as print_r() handles the problem of infinitely-deep arrays for you quite nicely.

Matt (2009-09-14 12:53:03)

Here is another version that parses the print_r() output. I tried the one posted, but I had difficulties with it. I believe it has a problem with nested arrays. This handles nested arrays without issue as far as I can tell. 

<?php
function print_r_reverse($in) {
    
$lines explode("\n"trim($in));
    if (
trim($lines[0]) != 'Array') {
        
// bottomed out to something that isn't an array
        
return $in;
    } else {
        
// this is an array, lets parse it
        
if (preg_match("/(\s{5,})\(/"$lines[1], $match)) {
            
// this is a tested array/recursive call to this function
            // take a set of spaces off the beginning
            
$spaces $match[1];
            
$spaces_length strlen($spaces);
            
$lines_total count($lines);
            for (
$i 0$i $lines_total$i++) {
                if (
substr($lines[$i], 0$spaces_length) == $spaces) {
                    
$lines[$i] = substr($lines[$i], $spaces_length);
                }
            }
        }
        
array_shift($lines); // Array
        
array_shift($lines); // (
        
array_pop($lines); // )
        
$in implode("\n"$lines);
        
// make sure we only match stuff with 4 preceding spaces (stuff for this array and not a nested one)
        
preg_match_all("/^\s{4}\[(.+?)\] \=\> /m"$in$matchesPREG_OFFSET_CAPTURE PREG_SET_ORDER);
        
$pos = array();
        
$previous_key '';
        
$in_length strlen($in);
        
// store the following in $pos:
        // array with key = key of the parsed array's item
        // value = array(start position in $in, $end position in $in)
        
foreach ($matches as $match) {
            
$key $match[1][0];
            
$start $match[0][1] + strlen($match[0][0]);
            
$pos[$key] = array($start$in_length);
            if (
$previous_key != ''$pos[$previous_key][1] = $match[0][1] - 1;
            
$previous_key $key;
        }
        
$ret = array();
        foreach (
$pos as $key => $where) {
            
// recursively see if the parsed out value is an array too
            
$ret[$key] = print_r_reverse(substr($in$where[0], $where[1] - $where[0]));
        }
        return 
$ret;
    }
}

?>

Federico Bricker (2009-06-29 16:02:29)

Here is a nice version of print_r that prints things with colors and tables.
I've called it print_nice

<?php
function print_nice($elem,$max_level=10,$print_nice_stack=array()){
    if(
is_array($elem) || is_object($elem)){
        if(
in_array(&$elem,$print_nice_stack,true)){
            echo 
"<font color=red>RECURSION</font>";
            return;
        }
        
$print_nice_stack[]=&$elem;
        if(
$max_level<1){
            echo 
"<font color=red>nivel maximo alcanzado</font>";
            return;
        }
        
$max_level--;
        echo 
"<table border=1 cellspacing=0 cellpadding=3 width=100%>";
        if(
is_array($elem)){
            echo 
'<tr><td colspan=2 style="background-color:#333333;"><strong><font color=white>ARRAY</font></strong></td></tr>';
        }else{
            echo 
'<tr><td colspan=2 style="background-color:#333333;"><strong>';
            echo 
'<font color=white>OBJECT Type: '.get_class($elem).'</font></strong></td></tr>';
        }
        
$color=0;
        foreach(
$elem as $k => $v){
            if(
$max_level%2){
                
$rgb=($color++%2)?"#888888":"#BBBBBB";
            }else{
                
$rgb=($color++%2)?"#8888BB":"#BBBBFF";
            }
            echo 
'<tr><td valign="top" style="width:40px;background-color:'.$rgb.';">';
            echo 
'<strong>'.$k."</strong></td><td>";
            
print_nice($v,$max_level,$print_nice_stack);
            echo 
"</td></tr>";
        }
        echo 
"</table>";
        return;
    }
    if(
$elem === null){
        echo 
"<font color=green>NULL</font>";
    }elseif(
$elem === 0){
        echo 
"0";
    }elseif(
$elem === true){
        echo 
"<font color=green>TRUE</font>";
    }elseif(
$elem === false){
        echo 
"<font color=green>FALSE</font>";
    }elseif(
$elem === ""){
        echo 
"<font color=green>EMPTY STRING</font>";
    }else{
        echo 
str_replace("\n","<strong><font color=red>*</font></strong><br>\n",$elem);
    }
}
?>

Bob (2009-05-08 03:19:02)

Here is a function that formats the output of print_r as a expandable/collapsable tree list using HTML and JavaScript.
<?php
function print_r_tree($data)
{
    
// capture the output of print_r
    
$out print_r($datatrue);

    
// replace something like '[element] => <newline> (' with <a href="javascript:toggleDisplay('...');">...</a><div id="..." style="display: none;">
    
$out preg_replace('/([ \t]*)(\[[^\]]+\][ \t]*\=\>[ \t]*[a-z0-9 \t_]+)\n[ \t]*\(/iUe',"'\\1<a href=\"javascript:toggleDisplay(\''.(\$id = substr(md5(rand().'\\0'), 0, 7)).'\');\">\\2</a><div id=\"'.\$id.'\" style=\"display: none;\">'"$out);

    
// replace ')' on its own on a new line (surrounded by whitespace is ok) with '</div>
    
$out preg_replace('/^\s*\)\s*$/m''</div>'$out);

    
// print the javascript function toggleDisplay() and then the transformed output
    
echo '<script language="Javascript">function toggleDisplay(id) { document.getElementById(id).style.display = (document.getElementById(id).style.display == "block") ? "none" : "block"; }</script>'."\n$out";
}
?>
Pass it a multidimensional array or object and each sub-array/object will be hidden and replaced by a html link that will toggle its display on and off.
Its quick and dirty, but great for debugging the contents of large arrays and objects.
Note: You'll want to surround the output with <pre></pre>

sebasg37 at gmail dot com (2009-01-25 21:35:58)

If you have to catch the output without showing it at all at first (for example, if you want to append the print_r output to a file), you can do this:

<?php

ob_start
();
print_r$some_array );
$output ob_get_clean();

// if you want to append the print_r output of $some_array to, let's say, log.txt:

file_put_contents'log.txt'file_get_contents'log.txt' ) . $output )

?>

afisher8 at cox dot net (2008-12-17 08:53:47)

I use this all the time when debugging objects, but when you have a very large object with big arrays of sub-objects, it's easy to get overwhelmed with the large amount of output....sometimes you don't want to see absolutely every sub-object.

I made this function to debug objects while "hiding" sub-objects of certain types.  This also color codes the output for a more readable printout.

<?php

function wtf($var$arrayOfObjectsToHide=null$fontSize=11)
{
    
$text print_r($vartrue);

    if (
is_array($arrayOfObjectsToHide)) {
    
        foreach (
$arrayOfObjectsToHide as $objectName) {
    
            
$searchPattern '#('.$objectName.' Object\n(\s+)\().*?\n\2\)\n#s';
            
$replace "$1<span style=\"color: #FF9900;\">--&gt; HIDDEN - courtesy of wtf() &lt;--</span>)";
            
$text preg_replace($searchPattern$replace$text);
        }
    }

    
// color code objects
    
$text preg_replace('#(\w+)(\s+Object\s+\()#s''<span style="color: #079700;">$1</span>$2'$text);
    
// color code object properties
    
$text preg_replace('#\[(\w+)\:(public|private|protected)\]#''[<span style="color: #000099;">$1</span>:<span style="color: #009999;">$2</span>]'$text);
    
    echo 
'<pre style="font-size: '.$fontSize.'px; line-height: '.$fontSize.'px;">'.$text.'</pre>';
}

// example usage:
wtf($myBigObject, array('NameOfObjectToHide_1''NameOfObjectToHide_2'));

?>

vista_ at live dot se (2008-12-04 08:31:42)

Do you think it is difficult to see what print_r() returns?

<?php
   
echo '<pre>';
   
print_r($array);
   echo 
'</pre>';
?>

And if you have to write this many times in a page, use this:

<?php
   
function preint_r($array)
   {
      echo 
'<pre>';
      
print_r($array);
      echo 
'</pre>';
   }
?>

everett at myersnetwork dot com (2008-11-23 15:02:25)

I like the print_r() function as I am sure many of you do, however when I am working on a script via a browser the output it not easy to read so I have created my own variation hope this helps any of you guys who have had the same frustration.

Start File ###########################################
<?php
/*
File Name: print_ar.php
PHP: 5.2.3 
*/

function print_ar($array$count=0) {
    
$i=0;
    
$tab ='';
    while(
$i != $count) {
        
$i++;
        
$tab .= "&nbsp;&nbsp;|&nbsp;&nbsp;";
    }
    foreach(
$array as $key=>$value){
        if(
is_array($value)){
            echo 
$tab."[<strong><u>$key</u></strong>]<br />";
            
$count++;
            
print_ar($value$count);
            
$count--;
        }
        else{
            
$tab2 substr($tab0, -12);
            echo 
"$tab2$key: <strong>$value</strong><br />";
        }
        
$k++;
    }
    
$count--;
}

?>
End File ###########################################

Use is exactly like the print_r() function example;

<?php
require("print_ar.php");

$array = array(
        
"Main1" => array(
                
"Sub1" => "Data 1-1",
                
"Sub2" => "Data 1-2",
                
"Sub3" => "Data 1-3",
        ),

        
"Main2" =>
        array (
                
"Sub1" => "Data 2-1",
                
"Sub2" => "Data 2-2",
                
"Sub3" => "Data 2-3",
        )
);

print_ar($array);
?>

Will give you:
[Main1]
  |~ Sub1: Data 1-1
  |~ Sub2: Data 1-2
  |~ Sub3: Data 1-3
[Main2]
  |~ Sub1: Data 2-1
  |~ Sub2: Data 2-2
  |~ Sub3: Data 2-3

Vice:
Array ( [Main1] => Array ( [Sub1] => Data 1-1 [Sub2] => Data 1-2 [Sub3] => Data 1-3 ) [Main2] => Array ( [Sub1] => Data 2-1 [Sub2] => Data 2-2 [Sub3] => Data 2-3 ) )

kurt krueckeberg (2008-10-28 10:53:19)

This is an alternative for printing arrays. It bolds array values.

<?php
function print_array(&$a$str "")
{
    if (
$str[0]) {
        echo 
"$str =";
    }
    echo 
' array( ';
    foreach (
$a as $k => $v) {

        echo 
"[$k]".' => ';

        if (
is_array($v)) {
            
print_array($v);
        }
        else {    
               echo 
"<strong>$a[$k]</strong> ";
        }
    }
    echo 
')  ';
}
$a1 = array ("apples""oranges""pears");
$a2 = array ("potatos""green beans""squash");
$a3 = array ("euros""dollars""pesos""dinars");
$test range(19);
array_push($test, array ("fruit" => $a1"vegies" => $a2"money" => $a3));
print_array($test"test");
?>

schizo do not spamme duckie at gmail dot com (2008-10-07 05:00:13)

my take on the highlighted markupped debug function:

<?php
/**
 * print_array()
 * Does a var_export of the array and returns it between <pre> tags
 * 
 * @param mixed $var any input you can think of
 * @return string HTML
 */
function print_array($var)
{
    
$input =var_export($var,true);
    
$input preg_replace("! => \n\W+ array \(!Uims"" => Array ( "$input);
    
$input preg_replace("!array \(\W+\),!Uims""Array ( ),"$input);
    return(
"<pre>".str_replace('><?''>'highlight_string('<'.'?'.$inputtrue))."</pre>");
}
?>

brenden at beagleproductions dot com (2008-08-28 13:58:03)

Many developers have submitted bugs to the PHP development team with regards to print_r showing protected and private properties of objects (PHP 5). This is not a bug; sensitive information (ex. database connection object) should be encapsulated within a private member function of your class.

admin at swivelgames dot com (2008-08-17 13:44:23)

I was having problems using print_r because I didn't like the fact that if tags where included in the array it would still be parsed by the browsers.

Heres a simple fix for anyone who is having the same problem as I did. This will output your text properly for viewing through the browser instead of the browser's "view source" or CLI.

Script:
<?php

     $MyArray
[0]="<div align='center'>My Text</div>";

     echo 
"<pre>".htmlspecialchars(print_r($MyArray,true))."</pre>";

?>

Output:
<pre>Array
(
    [0] =&gt; &lt;div align='center'&gt;My Text&lt;/div&gt;
)
</pre>

mayank dot chaudhary dot 30 at gmail dot com (2008-08-01 18:51:46)

I use a function. Since browsers neglect extra spaces and line feeds.
<?php
function print_a($subject){
echo 
str_replace("=>","&#8658;",str_replace("Array","<font color=\"red\"><b>Array</b></font>",nl2br(str_replace(" "," &nbsp; ",print_r($subject,true)))));
}
?>

Anonymous (2008-06-28 13:21:52)

I have written a nice debugging function.
This function handles arrays beautifully.
<?php
//Debug variables, $i and $k are for recursive use
function DebugDisplayVar($input$name "Debug"$i "0"$k = array("Error")){
    if(
is_array($input))
    {    foreach (
$input as $i => $value){
            
$temp $k;
            
$temp[] = $i;
            
DebugDisplayVar($value$name$i$temp);}
    }else{
//if not array
        
echo "$".$name;//[$k]
        
foreach ($k as $i => $value){
            if(
$value !=="Error"){echo "[$value]";}
        }
        echo 
" = $input<br>";
}    }

//outputs 
Debug[0] = value
Debug
[1] = another value 
ect
...

?>

janci (2008-05-13 02:49:32)

You cannot use print_r(), var_dump() nor var_export() to get static member variables of a class. However, in PHP5 you can use Reflection classes for this:

<?php

$reflection 
= new ReflectionClass('Static');
print_r($reflection->getStaticProperties());

?>

sruwhof at intervisionit dot nl (2008-04-09 05:27:42)

@highstrike at gmail dot com 08-Jan-2008 02:34
You have an bug in your debug script, the script only prints public properties of the exported object.

If you want to export all object properties (public, private, protected) to an array, then simply cast the object to an array:

<?php
class some 
{
   public 
$pub 1;
   protected 
$prot 2;
   private 
$priv 3;

}
var_dump( (array) new some() );
?>

result:
--------------
array(3) {
  ["pub"]=>
  int(1)
  ["*prot"]=>
  int(2)
  ["somepriv"]=>
  int(3)
}

tylmann at corvent dot ch (2008-03-28 02:07:19)

There is a library to create nice output of variables, arrays, hash-tables and even objects. It is great for developing/debugging and looks very much better than any print_r output.

Usage:
<?php 
debug
::show($myVar'caption'); 
?>

You can download it for free at http://sourceforge.net/projects/phpcorestdfuncs

For an example take a look at http://demo.corvent.ch/stdfuncs/

helpful at maybe dot com (2008-03-06 20:13:41)

Another slight modification to the previous post to allow for empty array elements

added the following lines after the first preg_match block 
<?php
        
} else if ($expecting == && preg_match('/^\[(.+?)\] \=\>$/'$trim$matches)) { // array element
            // the array element is blank
            
list ($fullMatch$key) = $matches;
            
$topArray[$key] = $element;
        }

?>

anon at anon dot com (2008-02-29 10:30:33)

A slight modification to the previous post to allow for arrays containing mutli line strings. haven't fully tested it with everything, but seems to work great for the stuff i've done so far.

<?php

function print_r_reverse(&$output)
{
    
$expecting 0// 0=nothing in particular, 1=array open paren '(', 2=array element or close paren ')'
    
$lines explode("\n"$output);
    
$result null;
    
$topArray null;
    
$arrayStack = array();
    
$matches null;
    while (!empty(
$lines) && $result === null)
    {
        
$line array_shift($lines);
        
$trim trim($line);
        if (
$trim == 'Array')
        {
            if (
$expecting == 0)
            {
                
$topArray = array();
                
$expecting 1;
            }
            else
            {
                
trigger_error("Unknown array.");
            }
        }
        else if (
$expecting == && $trim == '(')
        {
            
$expecting 2;
        }
        else if (
$expecting == && preg_match('/^\[(.+?)\] \=\> (.+)$/'$trim$matches)) // array element
        
{
            list (
$fullMatch$key$element) = $matches;
            if (
trim($element) == 'Array')
            {
                
$topArray[$key] = array();
                
$newTopArray =& $topArray[$key];
                
$arrayStack[] =& $topArray;
                
$topArray =& $newTopArray;
                
$expecting 1;
            }
            else
            {
                
$topArray[$key] = $element;
            }
        }
        else if (
$expecting == && $trim == ')'// end current array
        
{
            if (empty(
$arrayStack))
            {
                
$result $topArray;
            }
            else 
// pop into parent array
            
{
                
// safe array pop
                
$keys array_keys($arrayStack);
                
$lastKey array_pop($keys);
                
$temp =& $arrayStack[$lastKey];
                unset(
$arrayStack[$lastKey]);
                
$topArray =& $temp;
            }
        }
        
// Added this to allow for multi line strings.
    
else if (!empty($trim) && $expecting == 2)
    {
        
// Expecting close parent or element, but got just a string
        
$topArray[$key] .= "\n".$line;
    }
        else if (!empty(
$trim))
        {
            
$result $line;
        }
    }
   
    
$output implode(n$lines);
    return 
$result;
}

/**
 * @param string $output : The output of a multiple print_r calls, separated by newlines
 * @return mixed[] : parseable elements of $output
 */
function print_r_reverse_multiple($output)
{
    
$result = array();
    while ((
$reverse print_r_reverse($output)) !== NULL)
    {
        
$result[] = $reverse;
    }
    return 
$result;
}

$output '
Array
(
    [a] => apple
    [b] => banana
    [c] => Array
        (
            [0] => x
            [1] => y
            [2] => z
            [3] => Array
            (
                [nest] => yes
                [nest2] => Array
                (
                    [nest] => some more
                    asffjaskkd
                )
                [nest3] => o rly?
            )
        )
)

some extra stuff
'
;
var_dump(print_r_reverse($output), $output);

?>

This should output

array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  array(4) {
    [0]=>
    string(1) "x"
    [1]=>
    string(1) "y"
    [2]=>
    string(1) "z"
    [3]=>
    array(3) {
      ["nest"]=>
      string(3) "yes"
      ["nest2"]=>
      array(1) {
        ["nest"]=>
        string(40) "some more
                    asffjaskkd"
      }
      ["nest3"]=>
      string(6) "o rly?"
    }
  }
}
string(18) "nsome extra stuffn"

Added:
else if (!empty($trim) && $expecting == 2)
{
    // Expecting close parent or element, but got just a string
    $topArray[$key] .= "\n".$line;
}

ario at mail dot utexas dot [education - 3 letters] (2008-02-19 12:34:51)

This is a better print_r reverse algorithm, that works with arbitrary nested arrays.  Anything else it treats as strings.  The second function allows you to take a string with multiple print_r results concatenated, and returns the result of parsing each of them.

<?php

/**
 * @param string &$output : The output of a print_r call; this parameter is DESTRUCTIVE, and will be set to the remainder
 *                             of $output which is not parsed.
 * @return mixed : the first parseable element of $output
 */
function print_r_reverse(&$output)
{
    
$expecting 0// 0=nothing in particular, 1=array open paren '(', 2=array element or close paren ')'
    
$lines explode("\n"$output);
    
$result null;
    
$topArray null;
    
$arrayStack = array();
    
$matches null;
    while (!empty(
$lines) && $result === null)
    {
        
$line array_shift($lines);
        
$trim trim($line);
        if (
$trim == 'Array')
        {
            if (
$expecting == 0)
            {
                
$topArray = array();
                
$expecting 1;
            }
            else
            {
                
trigger_error("Unknown array.");
            }
        }
        else if (
$expecting == && $trim == '(')
        {
            
$expecting 2;
        }
        else if (
$expecting == && preg_match('/^\[(.+?)\] \=\> (.+)$/'$trim$matches)) // array element
        
{
            list (
$fullMatch$key$element) = $matches;
            if (
trim($element) == 'Array')
            {
                
$topArray[$key] = array();
                
$newTopArray =& $topArray[$key];
                
$arrayStack[] =& $topArray;
                
$topArray =& $newTopArray;
                
$expecting 1;
            }
            else
            {
                
$topArray[$key] = $element;
            }
        }
        else if (
$expecting == && $trim == ')'// end current array
        
{
            if (empty(
$arrayStack))
            {
                
$result $topArray;
            }
            else 
// pop into parent array
            
{
                
// safe array pop
                
$keys array_keys($arrayStack);
                
$lastKey array_pop($keys);
                
$temp =& $arrayStack[$lastKey];
                unset(
$arrayStack[$lastKey]);
                
$topArray =& $temp;
            }
        }
        else if (!empty(
$trim))
        {
            
$result $line;
        }
    }
    
    
$output implode(n$lines);
    return 
$result;
}

/**
 * @param string $output : The output of a multiple print_r calls, separated by newlines
 * @return mixed[] : parseable elements of $output
 */
function print_r_reverse_multiple($output)
{
    
$result = array();
    while ((
$reverse print_r_reverse($output)) !== NULL)
    {
        
$result[] = $reverse;
    }
    return 
$result;
}

$output '
Array
(
    [a] => apple
    [b] => banana
    [c] => Array
        (
            [0] => x
            [1] => y
            [2] => z
            [3] => Array
            (
                [nest] => yes
                [nest2] => Array
                (
                    [nest] => some more
                )
                [nest3] => o rly?
            )
        )
)

some extra stuff
'
;
var_dump(print_r_reverse($output), $output);

?>

The above example will output:

array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  array(4) {
    [0]=>
    string(1) "x"
    [1]=>
    string(1) "y"
    [2]=>
    string(1) "z"
    [3]=>
    array(3) {
      ["nest"]=>
      string(3) "yes"
      ["nest2"]=>
      array(1) {
        ["nest"]=>
        string(9) "some more"
      }
      ["nest3"]=>
      string(6) "o rly?"
    }
  }
}
string(20) "
some extra stuff
"

Goose (2008-02-06 15:31:07)

A one line command that serves to nl2br but have it so it displays in html is
function nl2br2($arg){print(nl2br(str_replace(' ','&nbsp;',print_r($arg,true))));}

Kokos (2008-01-31 04:52:55)

A simple function that will output an array more easily to read than print_r();

<?php
function echo_array($array,$return_me=false){
    if(
is_array($array) == false){
        
$return "The provided variable is not an array.";
    }else{
        foreach(
$array as $name=>$value){
            if(
is_array($value)){
                
$return .= "";
                
$return .= "['<b>$name</b>'] {<div style='margin-left:10px;'>\n";
                
$return .= echo_array($value,true);
                
$return .= "</div>}";
                
$return .= "\n\n";
            }else{
                if(
is_string($value)){
                    
$value "\"$value\"";
                }
                
$return .= "['<b>$name</b>'] = $value\n\n";
            }
        }
    }
    if(
$return_me == true){
        return 
$return;
    }else{
        echo 
"<pre>".$return."</pre>";
    }
}
?>

highstrike at gmail dot com (2008-01-08 05:34:35)

made 2 nifty functions based of what some people contributed here. Hope you find them usefull

usage ... call for the dump function. EG: dump($array, "Array dump");

<?php
////////////////////////////////////////////////////////
// Function:         dump
// Inspired from:     PHP.net Contributions
// Description: Helps with php debugging

function dump(&$var$info FALSE)
{
    
$scope false;
    
$prefix 'unique';
    
$suffix 'value';
  
    if(
$scope$vals $scope;
    else 
$vals $GLOBALS;

    
$old $var;
    
$var $new $prefix.rand().$suffix$vname FALSE;
    foreach(
$vals as $key => $val) if($val === $new$vname $key;
    
$var $old;

    echo 
"<pre style='margin: 0px 0px 10px 0px; display: block; background: white; color: black; font-family: Verdana; border: 1px solid #cccccc; padding: 5px; font-size: 10px; line-height: 13px;'>";
    if(
$info != FALSE) echo "<b style='color: red;'>$info:</b><br>";
    
do_dump($var'$'.$vname);
    echo 
"</pre>";
}

////////////////////////////////////////////////////////
// Function:         do_dump
// Inspired from:     PHP.net Contributions
// Description: Better GI than print_r or var_dump

function do_dump(&$var$var_name NULL$indent NULL$reference NULL)
{
    
$do_dump_indent "<span style='color:#eeeeee;'>|</span> &nbsp;&nbsp; ";
    
$reference $reference.$var_name;
    
$keyvar 'the_do_dump_recursion_protection_scheme'$keyname 'referenced_object_name';

    if (
is_array($var) && isset($var[$keyvar]))
    {
        
$real_var = &$var[$keyvar];
        
$real_name = &$var[$keyname];
        
$type ucfirst(gettype($real_var));
        echo 
"$indent$var_name <span style='color:#a2a2a2'>$type</span> = <span style='color:#e87800;'>&amp;$real_name</span><br>";
    }
    else
    {
        
$var = array($keyvar => $var$keyname => $reference);
        
$avar = &$var[$keyvar];
    
        
$type ucfirst(gettype($avar));
        if(
$type == "String"$type_color "<span style='color:green'>";
        elseif(
$type == "Integer"$type_color "<span style='color:red'>";
        elseif(
$type == "Double"){ $type_color "<span style='color:#0099c5'>"$type "Float"; }
        elseif(
$type == "Boolean"$type_color "<span style='color:#92008d'>";
        elseif(
$type == "NULL"$type_color "<span style='color:black'>";
    
        if(
is_array($avar))
        {
            
$count count($avar);
            echo 
"$indent. ($var_name "$var_name => ":"") . "<span style='color:#a2a2a2'>$type ($count)</span><br>$indent(<br>";
            
$keys array_keys($avar);
            foreach(
$keys as $name)
            {
                
$value = &$avar[$name];
                
do_dump($value"['$name']"$indent.$do_dump_indent$reference);
            }
            echo 
"$indent)<br>";
        }
        elseif(
is_object($avar))
        {
            echo 
"$indent$var_name <span style='color:#a2a2a2'>$type</span><br>$indent(<br>";
            foreach(
$avar as $name=>$valuedo_dump($value"$name"$indent.$do_dump_indent$reference);
            echo 
"$indent)<br>";
        }
        elseif(
is_int($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
        elseif(
is_string($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color\"$avar\"</span><br>";
        elseif(
is_float($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color$avar</span><br>";
        elseif(
is_bool($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $type_color".($avar == "TRUE":"FALSE")."</span><br>";
        elseif(
is_null($avar)) echo "$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> {$type_color}NULL</span><br>";
        else echo 
"$indent$var_name = <span style='color:#a2a2a2'>$type(".strlen($avar).")</span> $avar<br>";

        
$var $var[$keyvar];
    }
}
?>

bart at mediawave dot nl (2007-10-30 16:27:05)

Here's a PHP version of print_r which can be tailored to your needs. Shows protected and private properties of objects and detects recursion (for objects only!). Usage:

void u_print_r ( mixed $expression [, array $ignore] )

Use the $ignore parameter to provide an array of property names that shouldn't be followed recursively.

<?php

function u_print_r($subject$ignore = array(), $depth 1$refChain = array()) 
{
    if (
$depth 20) return;
    if (
is_object($subject)) {
        foreach (
$refChain as $refVal)
            if (
$refVal === $subject) {
                echo 
"*RECURSION*\n";
                return;
            }
        
array_push($refChain$subject);
        echo 
get_class($subject) . " Object ( \n";
        
$subject = (array) $subject;
        foreach (
$subject as $key => $val)
            if (
is_array($ignore) && !in_array($key$ignore1)) {
                echo 
str_repeat(" "$depth 4) . '[';
                if (
$key{0} == "\0") {
                    
$keyParts explode("\0"$key);
                    echo 
$keyParts[2] . (($keyParts[1] == '*')  ? ':protected' ':private');
                } else
                    echo 
$key;
                echo 
'] => ';
                
u_print_r($val$ignore$depth 1$refChain);
            }
        echo 
str_repeat(" ", ($depth 1) * 4) . ")\n";
        
array_pop($refChain);
    } elseif (
is_array($subject)) {
        echo 
"Array ( \n";
        foreach (
$subject as $key => $val)
            if (
is_array($ignore) && !in_array($key$ignore1)) {
                echo 
str_repeat(" "$depth 4) . '[' $key '] => ';
                
u_print_r($val$ignore$depth 1$refChain);
            }
        echo 
str_repeat(" ", ($depth 1) * 4) . ")\n";
    } else
        echo 
$subject "\n";
}

?>

Example:

<?php

class test {

    public 
$var1 'a';
    protected 
$var2 'b';
    private 
$var3 'c';
    protected 
$array = array('x''y''z');

}

$test = new test();
$test->recursiveRef $test;
$test->anotherRecursiveRef->recursiveRef $test;
$test->dont->follow 'me';

u_print_r($test, array('dont'));

?>

Will produce:

test Object ( 
    [var1] => a
    [var2:protected] => b
    [var3:private] => c
    [array:protected] => Array ( 
        [0] => x
        [1] => y
        [2] => z
    )
    [recursiveRef] => *RECURSION*
    [anotherRecursiveRef] => stdClass Object ( 
        [recursiveRef] => *RECURSION*
    )
)

php at deboom dot biz (2007-09-21 05:17:33)

If you need to import an print_R output back to an array you could use this.

This could also be (ab)used to convert a object into a array...

<?php
function object2array($printr) {                    
        
$newarray = array();        
        
$a[0] = &$newarray;        
        if (
preg_match_all('/^\s+\[(\w+).*\] => (.*)\n/m'$printr$match)) {                        
            foreach (
$match[0] as $key => $value) {    
                (int)
$tabs substr_count(substr($value0strpos($value"[")), "        ");                
                if (
$match[2][$key] == 'Array' || substr($match[2][$key], -6) == 'Object') {                    
                    
$a[$tabs+1] = &$a[$tabs][$match[1][$key]];
                }                            
                else {
                    
$a[$tabs][$match[1][$key]] = $match[2][$key];                    
                }
            }
        }    
        return 
$newarray;    
    }
?>

motin at demomusic dot nu (2007-06-19 16:01:09)

This works around the hacky nature of print_r in return mode (using output buffering for the return mode to work is hacky...):

<?php
/**
  * An alternative to print_r that unlike the original does not use output buffering with
  * the return parameter set to true. Thus, Fatal errors that would be the result of print_r
  * in return-mode within ob handlers can be avoided.
  *
  * Comes with an extra parameter to be able to generate html code. If you need a
  * human readable DHTML-based print_r alternative, see http://krumo.sourceforge.net/
  *
  * Support for printing of objects as well as the $return parameter functionality
  * added by Fredrik Wollsén (fredrik dot motin at gmail), to make it work as a drop-in
  * replacement for print_r (Except for that this function does not output 
  * paranthesises around element groups... ;) )
  *
  * Based on return_array() By Matthew Ruivo (mruivo at gmail)
  * (http://se2.php.net/manual/en/function.print-r.php#73436)
  */
function obsafe_print_r($var$return false$html false$level 0) {
    
$spaces "";
    
$space $html "&nbsp;" " ";
    
$newline $html "<br />" "\n";
    for (
$i 1$i <= 6$i++) {
        
$spaces .= $space;
    }
    
$tabs $spaces;
    for (
$i 1$i <= $level$i++) {
        
$tabs .= $spaces;
    }
    if (
is_array($var)) {
        
$title "Array";
    } elseif (
is_object($var)) {
        
$title get_class($var)." Object";
    }
    
$output $title $newline $newline;
    foreach(
$var as $key => $value) {
        if (
is_array($value) || is_object($value)) {
            
$level++;
            
$value obsafe_print_r($valuetrue$html$level);
            
$level--;
        }
        
$output .= $tabs "[" $key "] => " $value $newline;
    }
    if (
$return) return $output;
      else echo 
$output;
}
?>

Built on a function earlier posted in these comments as stated in the Doc comment. Cheers! /Fredrik (Motin)

mrasnika at users dot sourceforge dot net (2007-04-26 11:30:39)

We can all agree that print_r() output is very spartan looking. The debug data needs to be organized better, and presented in a graceful way. In the era of Web 2.0 it is somewhat strange to use plain text to dump information. A DHTML powered informatiion dumping tool will be quite better - like the the open-source alternative of print_r(); -- Krumo (http://krumo.sourceforge.net).
It renders the output using DHTML and collapsible nodes, it's layout is "skinable" and you can change it to fit your aesthetic taste. Krumo makes the output "human-readable" for real :) Plus it is compliant with both PHP4 and PHP5. Plus it detects "reference recursion". Plus you can use it to dump all various sort of data like debug back-traces, the superglobals ($_SERVER, $_ENV, $_REQUEST, $_COOKIE, $_GET, $_POST, $_SESSION), all the included files, all the declared classes, all the declared constants, all your PHP settings, all your php.ini values (if it is readable), all the loaded extensions, all the HTTP request headers, all the declared interfaces (for PHP5), all the file paths from INCLUDE_PATH, all the values of any particular INI file. Additionally it is designed to be easy to use - for example you can disable all the Krumo dumps instead of cleaning your code out of all print_r()'s and var_dump()'s. Anyway, if you check the site (http://krumo.sourceforge.net), you can found a lot of examples, demonstrations, documentation and all sort of helpful information.

Enthusiastic PHPers (2007-03-22 12:03:44)

We had an interesting problem dumping an object that
contained embedded HTML. The application makes use
of buffer manipulation functions, so print_r's 2nd argument
wasn't helpful. Here is how we solved the problem:
$object = new ObjectContainingHTML();
$savedbuffercontents = ob_get_clean();
print_r($object);
$print_r_output = ob_get_clean();
ob_start();
echo $savedbuffercontents;
echo htmlentities($print_r_output);

mading25 at hotmail dot com (2007-03-01 11:34:20)

None of the function to output to HTML was working for me so I had to write something that suited my needs. It's probably super not efficient but, hey it works well for me on a small scale.
function print_r_html($data,$return_data=false)
{
$data = print_r($data,true);
$data = str_replace( " ","&nbsp;", $data);
$data = str_replace( "\r\n","<br>\r\n", $data);
$data = str_replace( "\r","<br>\r", $data);
$data = str_replace( "\n","<br>\n", $data);
if (!$return_data)
echo $data;
else
return $data;
}
Simple, isn't? :)

Matthew Ruivo (mruivo at gmail) (2007-02-22 22:47:40)

For those of you needing to print an array within a buffer callback function, I've created this quick function. It simply returns the array as a readable string rather than printing it. You can even choose whether to return it in normal text-mode or HTML. It's recursive, so multi-dimensial arrays are supported. I hope someone finds this useful!

<?php

    
function return_array($array$html false$level 0) {
        
$space $html "&nbsp;" " ";
        
$newline $html "<br />" "\n";
        for (
$i 1$i <= 6$i++) {
            
$spaces .= $space;
        }
        
$tabs $spaces;
        for (
$i 1$i <= $level$i++) {
            
$tabs .= $spaces;
        }
        
$output "Array" $newline $newline;
        foreach(
$array as $key => $value) {
            if (
is_array($value)) {
                
$level++;
                
$value return_array($value$html$level);
                
$level--;
            }
            
$output .= $tabs "[" $key "] => " $value $newline;
        }
        return 
$output;
    }

?>

sakabako at gmail dot com (2007-02-07 12:45:08)

I've got four functions for printing arrays out in a readable fashion, I hope someone finds them useful.
//prints an array in a HTML table. Top row is the keys.
function table( $array ) {
$array = array_values( $array );

$keys = array_keys( $array[0] );

echo '<table border="1"><tr>';
foreach( $keys as $key ) {
echo '<td>'.$key.'</td>';
}
echo '</tr>';

foreach( $array as $row ) {
echo '<tr>';
foreach( $row as $value ) {
echo '<td>'.$value.'</td>';
}
echo '</tr>';
}
echo '</table>';
}
//print_r enclosed in a <pre>, except it will always print something, even if the variable is null, number 0 or false. It also lets you label the dump.
function dump( $var, $label=null ) {
if( $var === '' or $var === null or $var === 0 ) {
var_dump( $var );
return;
}
echo '<pre style="text-align: left; font-size: 10px;">';
if( $label ) {
echo $label."\n";
}
print_r( $var );
echo '</pre>';
}
//This one gives you output you can copy and paste back into your PHP code to recreate the array.
function dump_array( $array, $tabs=1 ) {
$html = "<pre style=\"text-align: left; font-size: 10px;\">array( \n";
foreach( $array as $key => $val ) {
$html .= str_repeat( "\t", $tabs )."'$key' => ";
if( is_array( $val ) ) {
$html .= dump_array( $array, $tabs+1 );
} else {
$html .= "'$val',\n";
}
}
$html .= ')</pre>';
return $html;
}
//just add header( 'content-type: application/vnd.ms-excel' ) and you've got an excel file.
function excel( $array ) {
$array = array_values( $array );

$keys = array_keys( $array[0] );

foreach( $keys as $key ) {
echo $key."\t";
}
echo "\n";

foreach( $array as $row ) {
foreach( $row as $value ) {
echo $value."\t";
}
echo "\n";
}
}

markus (at) maxxmaster (dot) org (2007-01-17 06:11:19)

i've been using a similar idea like Sawey's for quite a long time, 
but was always disappointed that you don't see the name of the 
variable passed to the function (eg calling it many times, you don't 
know which value was provided by a certain variable at a certain time). 
so i combined sawey's idea with one found on php.net to solve that problem.
for shellscripting the function only uses <pre>-tags when called in the web.

<?php
/* how print_r should be ;) */
function my_r(&$var$scope=false$label=false){

  if (
is_string($scope) && $label==false$label=$scope;
  if (!
is_array($scope)) $scope = &$GLOBALS;

  
$origin $var;
  
$var $checker "very_weird_value#".rand()."#isnt_it";
  
$vname false;

  foreach (
$scope as $key => $value){
    if (
$value === $checker){ $vname "\$".$key; }
    if (
is_array($value) && $key!="GLOBALS"){
      if (
$pfad=aver($var,$value)){ 
        
$vname "\$${key}[\""implode("\"][\"",$pfad)."\"]"
      }
    }
    if (
is_object($value)){
      if (
$pfad=aver($var,get_object_vars($value))){
        if (
sizeof($pfad)<2$vname "\$${key}->".$pfad[0];
        else{
          
$vname ="\$${key}->".$pfad[0];
          
$vname.="[\"".implode("\"][\""array_slice($pfad,1))."\"]";
        }
      }
    }
    if (
$vname) break;
  }
  
$var $origin;

  if (
$_SERVER["SERVER_NAME"] && !isset($_SERVER["TERM"])) echo "<pre>";
  if (
$vname){
    echo 
$vname;
    if (
$label) echo " #" $label "# ";
    else echo 
": ";
  }else{
    if (
$label) echo "$label: ";
  }
  
print_r($var);
  if (
$_SERVER["SERVER_NAME"] && !isset($_SERVER["TERM"])) echo "</pre>";
}

/* this function is needed to check in multidimensional arrays
if the value of interest exists. if yes, the path is returned */
function aver($needle,$haystack) { // array value exists recursive
  
foreach($haystack as $key=>$val) {
    if(
is_array($val) && $needle != $val && $key != "GLOBALS") { 
      if(
$foo=aver($needle,$val)) return array_merge(array($key),$foo);
    }elseif(
$val === $needle) return array($key);
  }
  return 
false;
}
?>

markus (at) maxxmaster (d0t) org (2007-01-17 05:33:43)

Explanation:
The problem with figuring out what value is what key in that variables scope is that several variables might have the same value.  To remedy this, the variable is passed by reference and its value is then modified to a random value to make sure there will be a unique match.  Then we loop through the scope ( semi recursively ) the variable is contained in and when there is a match of our modified value, we can grab the correct key and output the name.

Bugs:
You can see in the 5th Example, that the so-called non-existant variable infact exists ;|, the problem with referenced variables (as used in the my_r function) is, that they have to exist at call-time to reference them. that is why my_r("test") will result in a fatal error. if you have ideas to solve that, don't hesitate to mention them.

Examples:

1.  Use of a variable contained in the global scope (default):
<?php
  $my_global_variable 
= array("nice""try""guybrush");
  
my_r($my_global_variable); 

/* Outputs:  
$my_global_variable: Array
(
    [0] => nice
    [1] => try
    [2] => guybrush
)
*/
?>

2.  Use of a local variable (in a function):
<?php
function my_local_function()
{
  
$my_local_variable = array("nice""try""guybrush");
  
my_r($my_local_variable,get_defined_vars()); 
}
my_local_function();

/* Outputs:  
$my_local_variable: Array
(
    [0] => nice
    [1] => try
    [2] => guybrush
)
*/
?>

3.  Use of an object property:
<?php
class myclass{
  public function 
__constructor(){ // depending on php version ;)
    
$this->my_object_property = array("nice""try"name => array("guybrush"));
  }
  public function 
myclass(){ // depending on php version ;)
    
$this->my_object_property = array("nice""try"name => array("guybrush"));    
  }
}

$obj = new myclass;
my_r($obj->my_object_property); 
/* Outputs: 
$obj->my_object_property: Array
(
    [0] => nice
    [1] => try
    [name] => Array
        (
            [0] => guybrush
        )

)
*/
?>

4. Use of a sub-array and an additional label
<?php
$foo
=array("nice","try",name => array("guybrush","threapwood"))
my_r($foo["name"],"position 1");
/* Outputs:
$foo["name"] #position 1# Array
(
    [0] => guybrush
    [1] => threapwood
)
*/
?>

5. Use of non existant Variables (standard-behaviour of print_r)
<?php
my_r
($foo=array("nice","try","guybrush"));
/* Outputs:
Array
(
    [0] => nice
    [1] => try
    [2] => guybrush
)
*/
?>

SaWey @ localdomain (2007-01-15 11:44:46)

I've seen a lot of tries to give an easy way to output the "print_r" info in a decent way in you favorite browser.
Here's mine:
echo ("<pre>");
print_r("-->here goes your data to output<--");
echo ("<pre>");
I personaly think this is the easyest way.
Grz

auditor400 at gmail dot com (2006-11-02 07:56:40)

some functions I find useful for debugging.
/**
* dump the object in a base.class.php :: print_r2() fashon
this function is for debugging purposes only (obviously)
@see d2()
@param $obj an array of elements, that may have elements that are also arrays.
@param $color the color of the output (useful, when you need to call this several times,
and you need a certain structure to stand out from the others, or simply to differentiate them)
color-coding stuff is a great wa to work, consider this:
@code
p2($struct,'red');
@endcode
to find the function call, just search "red".
in case you find yourself lost, you can always sue the line numbers, @see $dinfo
@param $dinfo see http://www.php.net/debug_backtrace for nifo on debug info.,
0: no info, 1: function call, 2: full backtrace.
@param $title simple remarks you can put to aid you in development. i.e.
@code
$a=array(1,2,3,5,6)

//this
p2($a,'',0,'the numbers');
//is more meaningful than this:
p2($a);
@code
This is particulary true when dealing with many p2()
It is recomended that you *don't* delete p2()'s calls from your code,
but rather document them:
@code

//insightfull comments about spected output
//p2($a123,'',1,'Items in list')
@endcode
or, if you feel more confortable with logging, use this:
$this->log(gp2($struct)); @see gp2()
You can also use p2() as a call trace: helper
@code
function a(){
b();
}
function b(){
c();
}
function d(){
a();
}
function c(){
p2(1,'',2,'backtrace');
}
d();
@endcode

note the use of p2(1), as a simple backtrace enables, you can use
p2($anything,'',2) to display the log, or p2($anything) to show the call route.
the call route follows the following format:
@ file : function : function_call_line_number -> current_line_number
i.e.
@std.php:filter_link():1222->2142
where current line number is the line where the p2() call is, and "function call number"
is the line where the current function was called from (useful as hell).
--
* */
function p2($obj,$color='black',$dinfo=1,$title=''){
//echo();
$dbg=debug_backtrace();
if($dinfo!=0){
//':'.$dbg[1]['class'].
$dinfo="@".basename($dbg[1]['file']).':'.$dbg[1]['function'].'():'.
$dbg[1]['line'].'->'.$dbg[0]['line']."\n";
}
if($dinfo==2){
$dinfo.=print_r(debug_backtrace(),true);
}
if($color==''){$color='rgb(50,50,200)';}
echo("<h3 style='color:$color'>".$title.'</h3><xmp style="color:'.$color.'">'.
$dinfo.print_r($obj,1)."</xmp>");
}
function gp2($obj,$color='black'){
return("<xmp style='color:$color'>".print_r($obj,1)."</xmp>");
}
/**
* @see d2()
* */
function d2_recursive($obj,$label='',$color='rgb(100,100,100)'){
if(is_array($obj)){
$dx="\n<table style='border:1px solid ".$color."' cellspacing=0 cellpadding=2 width=100%>";
if($label!=''){
$dx.="\n<tr><td style='background-color:".$color.";border:1px solid ".$color.
"' colspan=2>".$label."</td></tr>";
}
foreach($obj as $k=>$v){
$dx.="\n<tr><td style='width:1%;color:white;font-weight:bold;font-family:verdana;".
"font-size:10pt;background-color:".$color.";border:1px solid ".$color."'>".$k
.'</td><td style="border:1px solid '.$color.'">';
$dx.=d2_recursive($v,'',$color)."</td></tr>";
}
$dx.="\n</table>";
}else{
$dx=$obj;
}
return($dx);
}
/** \brief nice html object inspector
* @see p2()
* */
function d2($obj,$label='',$color='black'){
echo("\n<!--DUMP:$label START-->\n".d2_recursive($obj,$label,$color)."\n<!--DUMP END-->\n");
}

Dmitry Kochin <dco at mail dot ru> (2006-09-08 01:20:12)

Sometimes print_r produces large output, especially when the data hierarchy is too deep. It is very difficult to analyze the dump about 1Mb length.

It would be great to have some way to fold arrays and objects and to look deeper into hierarchy only on demand.

Here is the solution. Just pass the print_r output to debug_var function:

debug_var('title', print_r($var, true));

and it will produce nice html with folding option.

<?php
  ob_start
();
?>
Locals: Array
(
    [arr] => Array
        (
            [0] => Bon Object
                (
                    [n] => id
                    [v] => 1
                    [dv] => 
                    [dn] => 
                )

        )

    [b] => Bon Object
        (
            [n] => id
            [v] => 1
            [dv] => 
            [dn] => 
        )

    [k] => 0
    [row] => Array
        (
            [aid] => 1
            [bonus] => spell.id: 125;
            [req] => 
            [brcache] => 
            [auto] => 0
        )

    [sp] => 
)
<?php
  $str 
ob_get_contents(); 
  
ob_end_clean();

  
debug_var('locals'$str);

function 
debug_var($name,$data

    
$captured preg_split("/\r?\n/",$data); 
    print 
"<script>function toggleDiv(num){
      var span = document.getElementById('d'+num);
      var a = document.getElementById('a'+num);
      var cur = span.style.display;
      if(cur == 'none'){
        a.innerHTML = '-';
        span.style.display = 'inline';
      }else{
        a.innerHTML = '+';
        span.style.display = 'none';
      }
    }</script>"

    print 
"<b>$name</b>\n"
    print 
"<pre>\n"
    foreach(
$captured as $line
    { 
        print 
debug_colorize_string($line)."\n"
    } 
    print 
"</pre>\n"


function 
next_div($matches
{
  static 
$num 0;
  ++
$num;
  return 
"$matches[1]<a id=a$num href=\"javascript: toggleDiv($num)\">+</a><span id=d$num style=\"display:none\">(";
}

/** 
* colorize a string for pretty display 

* @access private 
* @param $string string info to colorize 
* @return string HTML colorized 
* @global 
*/ 
function debug_colorize_string($string

    
$string preg_replace("/\[(\w*)\]/i"'[<font color="red">$1</font>]'$string);
    
$string preg_replace_callback("/(\s+)\($/"'next_div'$string);
    
$string preg_replace("/(\s+)\)$/"'$1)</span>'$string);
    
/* turn array indexes to red */ 
    /* turn the word Array blue */ 
    
$string str_replace('Array','<font color="blue">Array</font>',$string); 
    
/* turn arrows graygreen */ 
    
$string str_replace('=>','<font color="#556F55">=></font>',$string);
    return 
$string;

?>

This example uses ideas from this article:
http://www.zend.com/zend/tut/tutorial-DebugLib.php

ohira (atto) web. de (2006-04-13 07:01:05)

Bases on thbley?s sript i use this one to log some actions.
It will return a tabbed like string which you can output or whatever.

Input fields like "Password" will not be shown.

<?php

function print_r_string($arr,$first=true,$tab=0
{
    
$output "";
    
$tabsign = ($tab) ? str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;',$tab) : '';
    if (
$first$output .= "<pre><br>\n";
    foreach(
$arr as $key => $val
    {
        switch (
gettype($val)) 
        {
            case 
"array":
                
$output .= $tabsign."[".htmlspecialchars($key)."] = array(".count($val).")<br>\n".$tabsign."(<br>\n";
                
$tab++;
                
$output .= print_r_string($val,false,$tab); 
                
$tab--;
                
$output .= $tabsign.")<br>\n"
            break;
            case 
"boolean":
                
$output .= $tabsign."[".htmlspecialchars($key)."] bool = '".($val?"true":"false")."'<br>\n"
            break;
            case 
"integer":
                
$output .= $tabsign."[".htmlspecialchars($key)."] int = '".htmlspecialchars($val)."'<br>\n"
            break;
            case 
"double":
                
$output .= $tabsign."[".htmlspecialchars($key)."] double = '".htmlspecialchars($val)."'<br>\n"
            break;
            case 
"string":
                
$output .= $tabsign."[".htmlspecialchars($key)."] string = '".((stristr($key,'passw')) ? str_repeat('*'strlen($val)) : htmlspecialchars($val))."'<br>\n"
            break;
            default:
                
$output .= $tabsign."[".htmlspecialchars($key)."] unknown = '".htmlspecialchars(gettype($val))."'<br>\n"
            break;
        }
    }
    if (
$first$output .= "</pre><br>\n";
    return 
$output;
}

echo 
print_r_string(array($_POST,$_GET)); // for Example
?>

sanya at hik dot hu (2006-04-05 07:13:39)

I find a possibly bug, when I wanted to print the structure of a DOMDocument or a DOMDocumentType object.
print_r() outputs the object type correctly, but the properties are missing.
$doc = $imp->createDocument();
$doc->loadXML($xmlString);
print_r($doc->doctype);
the code outputs:
DOMDocumentType Object
(
)
But the subobjects of $doc->doctype exist.

reinder at fake-address dot com (2006-01-31 09:09:36)

I always use this function in my code, because most of my functions return an Array or Boolean :

<?php

function printr $object $name '' ) {

    print ( 
'\'' $name '\' : ' ) ;

    if ( 
is_array $object ) ) {
        print ( 
'<pre>' )  ;
        
print_r $object ) ; 
        print ( 
'</pre>' ) ;
    } else {
        
var_dump $object ) ;
    }

}

?>

( print_r gives no output on FALSE and that can be annoying! )

thbley at gmail dot com (2005-11-16 12:10:24)

Here is a print_r that produces xml:
(now you can expand/collapse the nodes in your browser)

<?php
header
('Content-Type: text/xml; charset=UTF-8');
echo 
print_r_xml($some_var);

function 
print_r_xml($arr,$first=true) {
  
$output "";
  if (
$first$output .= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<data>\n";
  foreach(
$arr as $key => $val) { 
    if (
is_numeric($key)) $key "arr_".$key// <0 is not allowed
    
switch (gettype($val)) { 
      case 
"array":
        
$output .= "<".htmlspecialchars($key)." type='array' size='".count($val)."'>".
          
print_r_xml($val,false)."</".htmlspecialchars($key).">\n"; break;
      case 
"boolean":
        
$output .= "<".htmlspecialchars($key)." type='bool'>".($val?"true":"false").
          
"</".htmlspecialchars($key).">\n"; break;
      case 
"integer":
        
$output .= "<".htmlspecialchars($key)." type='integer'>".
          
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
      case 
"double":
        
$output .= "<".htmlspecialchars($key)." type='double'>".
          
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
      case 
"string":
        
$output .= "<".htmlspecialchars($key)." type='string' size='".strlen($val)."'>".
          
htmlspecialchars($val)."</".htmlspecialchars($key).">\n"; break;
      default:
        
$output .= "<".htmlspecialchars($key)." type='unknown'>".gettype($val).
          
"</".htmlspecialchars($key).">\n"; break;
    }
  }
  if (
$first$output .= "</data>\n";
  return 
$output;
}
  
?>

jamin42b at gmail dot com (2005-09-02 05:52:07)

Here's a short function that can export php arrays to javascript arrays.

<?php

function php_to_js($array$base) {
    
$js '';
    foreach (
$array as $key=>$val) {
        if (
is_array($val)) {
            
$js .= php_to_js($val$base.(is_numeric($key) ? '['.$key.']' "['".addslashes($key)."']"));
        } else {
            
$js .= $base;
            
$js .= is_numeric($key) ? '['.$key.']' "['".addslashes($key)."']";
            
$js .= ' = ';
            
$js .= is_numeric($val) ? ''.$val.'' "'".addslashes($val)."'";
            
$js .= ";\n";
        }
    }
    return 
$base." = new Array();\n".$js;
}

?>

Example use:

<?php
$my_array 
= array('gdsag' => 4'hello', array(56));
echo 
'<script>'.php_to_js($my_array).'</script>';
?>

This would output:

<script>
jsvarname = new Array();
jsvarname['gdsag'] = 4;
jsvarname[0] = 'hello';
jsvarname[1] = new Array();
jsvarname[1][0] = 5;
jsvarname[1][1] = 6;

</script>

Now the array is loaded in the browser as javascript. As you can see, it supports multidimensional arrays too.

warhog at warhog dot net (2005-08-11 17:01:13)

For very long arrays I have written a little function which formats an array quite nice and uses javascript for browsing it like a tree. The function is very customizable with the $style parameter.
For me it's of great use for browsing large array's, for example when those are used in language-files in some script and so on. It may even be used in "real" scripts for the "real" front-end, cause the tree can very easily be styled (look at the function or the outputted source and you'll see what i mean).

Here's the function:

<?php

function print_r_html($arr$style "display: none; margin-left: 10px;")
{ static 
$i 0$i++;
  echo 
"\n<div id=\"array_tree_$i\" class=\"array_tree\">\n";
  foreach(
$arr as $key => $val)
  { switch (
gettype($val))
    { case 
"array":
        echo 
"<a onclick=\"document.getElementById('";
        echo 
array_tree_element_$i."').style.display = ";
        echo 
"document.getElementById('array_tree_element_$i";
        echo 
"').style.display == 'block' ?";
        echo 
"'none' : 'block';\"\n";
        echo 
"name=\"array_tree_link_$i\" href=\"#array_tree_link_$i\">".htmlspecialchars($key)."</a><br />\n";
        echo 
"<div class=\"array_tree_element_\" id=\"array_tree_element_$i\" style=\"$style\">";
        echo 
print_r_html($val);
        echo 
"</div>";
      break;
      case 
"integer":
        echo 
"<b>".htmlspecialchars($key)."</b> => <i>".htmlspecialchars($val)."</i><br />";
      break;
      case 
"double":
        echo 
"<b>".htmlspecialchars($key)."</b> => <i>".htmlspecialchars($val)."</i><br />";
      break;
      case 
"boolean":
        echo 
"<b>".htmlspecialchars($key)."</b> => ";
        if (
$val)
        { echo 
"true"; }
        else
        { echo 
"false"; }
        echo  
"<br />\n";
      break;
      case 
"string":
        echo 
"<b>".htmlspecialchars($key)."</b> => <code>".htmlspecialchars($val)."</code><br />";
      break;
      default:
        echo 
"<b>".htmlspecialchars($key)."</b> => ".gettype($val)."<br />";
      break; }
    echo 
"\n"; }
  echo 
"</div>\n"; }

?>

The function as it is now does not support the $return parameter as print_r does and will create an endless loop like print_r did in php-versions < 4.0.3 when there is an element which contains a reference to a variable inside of the array to print out :-/

I've tested it with PHP 5.0.6 and PHP 4.2.3 - no problems except those already mentioned.

please e-mail me if you've got a solution for the problems i've mentioned, i myself are not able to solve them 'cause i don't know how the hell i can find out whether a variable is a reference or not.

nicky dot weber at siner dot de (2005-06-11 02:13:18)

Print arrays formatted for a browser easily:

<?php
function print_html_r$aData ) {
    echo 
nl2breregi_replace" "" "print_r$dataTRUE ) ) );    
}
?>

general at NOSPAMbugfoo dot com (2005-01-20 13:23:18)

You can't use print_r($var, TRUE) inside a function which is a callback from ob_start() or you get the following error:
Fatal error: print_r(): Cannot use output buffering in output buffering display handlers

易百教程