53

I have an array:

$a = array('foo' => 'fooMe');

and I do:

print_r($a);

which prints:

Array ( [foo] => printme )

Is there a function, so when doing:

needed_function('    Array ( [foo] => printme )');

I will get the array array('foo' => 'fooMe'); back?

Adrian Cid Almaguer
  • 7,815
  • 13
  • 41
  • 63
John Kar.
  • 605
  • 1
  • 7
  • 10
  • Just to add more context about the "why?", I encountered this excat same problem. A previous developer left behind code that parsed data from another platform and logged the results as print_r strings (because of it being friendly to human reading). Some time later, the need to re-parse this information arose, and the only record of it was the logs. – Flyingfenix Sep 18 '20 at 19:03
  • You can look here: https://blog.nixarsoft.com/2021/04/16/convert-print_r-result-to-json/ – kodmanyagha Apr 16 '21 at 14:49
  • @kodmanyagha that page doesn't deal with sub-arrays (need a recursive call when meeting `Array(`), nor with special cases. Anyway, the result of *print_r()* is non-deterministic as the key/value can contain the separators used by *print_r* or `\n` and nothing is escaped... – Déjà vu Jul 27 '21 at 07:19

11 Answers11

35

I actually wrote a function that parses a "stringed array" into an actual array. Obviously, it's somewhat hacky and whatnot, but it works on my testcase. Here's a link to a functioning prototype at http://codepad.org/idlXdij3.

I'll post the code inline too, for those people that don't feel like clicking on the link:

<?php
     /**
      * @author ninetwozero
      */
?>
<?php
    //The array we begin with
    $start_array = array('foo' => 'bar', 'bar' => 'foo', 'foobar' => 'barfoo');

    //Convert the array to a string
    $array_string = print_r($start_array, true);

    //Get the new array
    $end_array = text_to_array($array_string);

    //Output the array!
    print_r($end_array);

    function text_to_array($str) {

        //Initialize arrays
        $keys = array();
        $values = array();
        $output = array();

        //Is it an array?
        if( substr($str, 0, 5) == 'Array' ) {

            //Let's parse it (hopefully it won't clash)
            $array_contents = substr($str, 7, -2);
            $array_contents = str_replace(array('[', ']', '=>'), array('#!#', '#?#', ''), $array_contents);
            $array_fields = explode("#!#", $array_contents);

            //For each array-field, we need to explode on the delimiters I've set and make it look funny.
            for($i = 0; $i < count($array_fields); $i++ ) {

                //First run is glitched, so let's pass on that one.
                if( $i != 0 ) {

                    $bits = explode('#?#', $array_fields[$i]);
                    if( $bits[0] != '' ) $output[$bits[0]] = $bits[1];

                }
            }

            //Return the output.
            return $output;

        } else {

            //Duh, not an array.
            echo 'The given parameter is not an array.';
            return null;
        }

    }
?>
karllindmark
  • 6,031
  • 1
  • 26
  • 41
  • Doesn't work quite well - it removes spaces in key and value! http://codepad.org/GYL4M2xi – Trolley Mar 15 '13 at 09:29
  • @Elias I updated the script above, can't quite remember why I was replacing the spaces. Here's a link to a revised version (based on your code): http://codepad.org/od79B28T –  Mar 15 '13 at 14:25
  • 17
    For simple arrays this works, however for multidimensional array it fails. Just use [this](http://www.php.net/manual/en/function.print-r.php#93529). – machineaddict Jul 18 '13 at 07:41
  • I added a trim() to $bits[1] because it was adding a lot of empty space around the values. – phoenix Sep 13 '19 at 15:15
15

If you want to store an array as string, use serialize [docs] and unserialize [docs].

To answer your question: No, there is no built-in function to parse the output of print_r into an array again.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 2
    This answer avoids providing a solution to the question asked. We must assume that the OP (and other researchers that find this page) are in no position to modify the input structure. (If they could modify the input structure, there are plenty of other pages on SO that describe how to use `serialize`/`unserialize` and `json_encode()`/`json_decode()`.) – mickmackusa Mar 29 '21 at 05:17
9

No. But you can use both serialize and json_* functions.

$a = array('foo' => 'fooMe');
echo serialize($a);

$a = unserialize($input);

Or:

echo json_encode($a);

$a = json_decode($input, true);
cutsoy
  • 10,127
  • 4
  • 40
  • 57
  • 1
    The OP is not asking for alternative ways to encode/serialize the data. The OP has stated that the input is the output from `print_r()` and that text needs to be parsed. – mickmackusa Mar 29 '21 at 05:15
8

you cannot do this with print_r,
var_export should allow something similar, but not exactly what you asked for

http://php.net/manual/en/function.var-export.php

$val = var_export($a, true);
print_r($val);
eval('$func_val='.$val.';');
ajreal
  • 46,720
  • 11
  • 89
  • 119
7

There is a nice Online-Tool which does exatly what its name is:

print_r to json online converter

From a JSON Object its not far to creating an array with the json_decode function:

To get an array from this, set the second paramter to true. If you don't, you will get an object instead.

json_decode($jsondata, true);
makkus
  • 383
  • 4
  • 11
4

I think my function is cool too, works with nested arrays:

function print_r_reverse($input)
{
    $output = str_replace(['[', ']'], ["'", "'"], $input);
    $output = preg_replace('/=> (?!Array)(.*)$/m', "=> '$1',", $output);
    $output = preg_replace('/^\s+\)$/m', "),\n", $output);
    $output = rtrim($output, "\n,");
    return eval("return $output;");
}

NB: better not use this with user input data

Raphos
  • 163
  • 7
  • This one works as long as you do not have empty arrays like ```Array ( )``` A simple search and replace takes care of that limitation. – Tuaris Apr 09 '19 at 20:14
  • Does not take care of `stdClass Object`, number data type, multi-line string values, escaping quotes. – trincot Oct 22 '21 at 15:11
1

Here is a print_r output parser, producing the same expression in PHP syntax. It is written as an interactive Stack Snippet, so you can use it here:

function parse(s) {
    const quote = s => '"' + s.replace(/["\\]/g, '\\$&') + '"';
    const compress = indent => " ".repeat(((indent.length + 4) >> 3) * 4);
    return "$data = " + (s.replace(/\r\n?/g, "\n") + "\n").replace(
        /(Array|\w+ (Object)) *\n *\( *\n|^( *)(?:\[(?:(0|-?[1-9]\d*)|(.*?))\] => |(\) *\n+))|(-?\d+(?:\.\d+)?(?:E[-+]\d+)?)\n|(.*(?:\n(?! *\) *$| *\[.*?\] => ).*)*)\n/gm,
        (_, array, object, indent, index, key, close, number, string) => 
            object ? "(object) [\n"
                   : array ? "[\n"
                           : close ? compress(indent) + "],\n"
                                   : indent ? compress(indent) + (index ?? quote(key)) + " => "
                                            : (number ?? quote(string)) + ",\n"
    ).replace(/,\n$/, ";");
}

// I/O handling
const [input, output] = document.querySelectorAll("textarea");
(input.oninput = () => output.value = parse(input.value))();
textarea { width: 23em; height: 12em }
<table><tr><th>Input print_r format</th><th>Output PHP syntax</th></tr>
<tr><td><textarea>
Array
(
    [0] => example
    [1] => stdClass Object
        (
            [a[] => 1.43E+19
            ["] => quote
            [] => 
        )
)
</textarea></td><td><textarea readonly></textarea></td></tr></table>

Remarks

  • Don't remove any line breaks from the original print_r output. For instance, both the opening and closing parentheses after Array must appear on separate lines.
  • Don't change the spacing around => (one space before, one after).
  • As print_r does not distinguish between null, "" or false (it produces no output for these values), nor between true and 1 (both are output as 1), this converter will never produce null, false or true.
  • As print_r does not distinguish between numbers and strings (9 could represent a number or a string), this converter will assume that the data type is to be numeric when such ambiguity exists.
  • stdClass Object is supported and translates to (object) [...] notation
  • MyClass Object will be treated as if it was a stdClass object.
  • String literals in the output are double quoted and literal double quotes and backslashes are escaped.
trincot
  • 317,000
  • 35
  • 244
  • 286
0

Quick function (without checks if you're sending good data):

function textToArray($str)
{
    $output = [];

    foreach (explode("\n", $str) as $line) {

        if (trim($line) == "Array" or trim($line) == "(" or trim($line) == ")") {
            continue;
        }

        preg_match("/\[(.*)\]\ \=\>\ (.*)$/i", $line, $match);

        $output[$match[1]] = $match[2];
    }

    return $output;
}

This is the expected input:

Array
(
    [test] => 6
)
phoenix
  • 1,629
  • 20
  • 11
0

This is how I interpreted the question:

function parsePrintedArray($s){
    $lines = explode("\n",$s);
    $a = array();
    foreach ($lines as $line){
        if (strpos($line,"=>") === false)
            continue;
        $parts = explode('=>',$line);
        $a[trim($parts[0],'[] ')] = trim($parts[1]);
    }
    return $a;
}

Works for both objects and arrays:

$foo = array (
    'foo' => 'bar',
    'cat' => 'dog'
);

$s = print_r($foo,1);
$a = parsePrintedArray($s);
print_r($a);

Output:

Array
(
    [foo] => bar
    [cat] => dog
) 

doesnt work on nested arrays, but simple and fast.

Danial
  • 1,496
  • 14
  • 15
  • Does not take care of nested arrays, `stdClass Object` (it returns an array not an object), number data type, multi-line string values, strings that start/end with spaces. – trincot Oct 22 '21 at 15:14
-1

use

var_export(array('Sample array', array('Apple', 'Orange')));

Output:

array (
  0 => 'Sample array',
  1 => 
  array (
    0 => 'Apple',
    1 => 'Orange',
  ),
)
wnull
  • 217
  • 6
  • 21
Khaldoon Masud
  • 300
  • 2
  • 4
-1

json_encode() and json_decode() function will do it.

$asso_arr = Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83);
$to_string = json_encode($asso_arr);

It will be as a json format {"779":"79","780":"80","782":"82","783":"83"}

Then we will convert it into json_decode() then it gives associative array same as original:

print_r(json_decode($to_string));

Output will be Array([779] => 79 => [780] => 80 [782] => 82 [783] => 83) in associative array format.

Don't Panic
  • 13,965
  • 5
  • 32
  • 51
  • 1
    This is the correct answer to a different question. This post in no way attempts to parse the text generated by `print_r()`. – mickmackusa Mar 29 '21 at 05:12