-
-
Save simivar/037b13a9bbd53ae5a092d8f6d9828bc3 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* I've published a fully-tested Composer library with type-casting. | |
* @see https://github.com/simivar/reverse-print-r | |
*/ | |
/** | |
* Matt: core | |
* Trixor: object handling | |
* lech: Windows suppport | |
* simivar: null support | |
* | |
* @see http://php.net/manual/en/function.print-r.php | |
**/ | |
function print_r_reverse($input) { | |
$lines = preg_split('#\r?\n#', trim($input)); | |
if (trim($lines[ 0 ]) != 'Array' && trim($lines[ 0 ]) != 'stdClass Object') { | |
// bottomed out to something that isn't an array or object | |
if ($input === '') { | |
return null; | |
} | |
return $input; | |
} else { | |
// this is an array or object, lets parse it | |
$match = array(); | |
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); | |
} | |
} | |
} | |
$is_object = trim($lines[ 0 ]) == 'stdClass Object'; | |
array_shift($lines); // Array | |
array_shift($lines); // ( | |
array_pop($lines); // ) | |
$input = implode("\n", $lines); | |
$matches = array(); | |
// 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", $input, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); | |
$pos = array(); | |
$previous_key = ''; | |
$in_length = strlen($input); | |
// 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($input, $where[ 0 ], $where[ 1 ] - $where[ 0 ])); | |
} | |
return $is_object ? (object)$ret : $ret; | |
} | |
} |
@MagicTrixor: fixed
Thanks for sharing, what is the license on this code? Also, any interest in turning it into a composer package (I'm willing to set that up if needed).
@digitalowlnyc it was first posted on php.net note's section on print_r. From what I gather all notes are shared on the same license as PHP documentation (see here), so it's CC BY 3.0.
I don't think there is a composer package for that but I'll try to set something up soon and refactor it a little. If you feel like you need it now feel free to publish it yourself as it is CC BY 3.0.
you can use
if (trim($lines[ 0 ]) != 'Array' && !preg_match('/^\S+?\ Object$/',trim($lines[ 0 ])))
to support objects other than stdClass Object, for example it fixed this:
Replay Object
(
[id] => 1106
[date] => 2020-02-22 09:57:28
[json] => Array
(
[id] => CForEIS28JPUV
[name] => Kontor
[type] => Office
[event] => Update
[subtype] => Office
[customerId] => S3
)
[url] => http://www.eS322
)
@divinity76 could you provide the source code of Replay
class? It will make nice test-case.
nothing more fancy than
class Replay
{
public $id;
public $date;
public $json;
}
.. the url-attribute was added post-construction
I've published a fully-tested Composer library with type-casting. See simivar/reverse-print-r if you want to use that.
if (trim($lines[ 0 ]) != 'Array' && trim($lines[ 0 ] != 'stdClass Object')) {
has a bug, it should be
if (trim($lines[ 0 ]) != 'Array' && trim($lines[ 0 ]) != 'stdClass Object') {
Cool for putting it here :)