Switch to the Czech version

Tuesday, 27 March 2012

Reverse print_r in PHP

This piece of PHP code saved my skin a few times already, better post it here for future reference:

<?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;
    }
}
?>


It parses the output of our beloved print_r function and returns it as the original value. I.e. serialization and unserialization. This function helped me retrieve nested array content from logs and to use the data again.

2 comments:

  1. not works for
    [0] => Array
    (
    [id] => 123
    [name] => Foo Bar
    [contactMe] =>
    [contactName] =>
    [contactEmail] =>
    )

    ReplyDelete
  2. That is actually not an array, based on the first line "[0] => Array" it is the first element of some other array.
    To make it work you have to change the first line to "Array".

    ReplyDelete