How create an array from the output of an array printed with print_r?

PhpArraysStringVariablesType Conversion

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

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

Solution 2 - Php

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.

Solution 3 - Php

For Array output with Subarrays, the solution provided by ninetwozero will not work, you can try with this function that works with complex arrays:

<?php

$array_string = "

Array
 (
   [0] => Array
    (
       [0] => STATIONONE
       [1] => 02/22/15 04:00:00 PM
       [2] => SW
       [3] => Array
            (
                [0] => 4.51
            )

        [4] => MPH
        [5] => Array
            (
                [0] => 16.1
            )

        [6] => MPH
    )

     [1] => Array
    (
        [0] => STATIONONE
        [1] => 02/22/15 05:00:00 PM
        [2] => S
        [3] => Array
            (
                [0] => 2.7
            )

        [4] => MPH
        [5] => Array
            (
                [0] => 9.61
            )

        [6] => MPH
    )
)
";

print_r(print_r_reverse(trim($array_string)));

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 == 1 && $trim == '(')
        {
            $expecting = 2;
        }
        else if ($expecting == 2 && 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 == 2 && $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;
}

?>

There is one tiny bug, if you have an empty value (empty string) it gets embedded in the value before.

Solution 4 - Php

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);

Solution 5 - Php

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.';');

Solution 6 - Php

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);

Solution 7 - Php

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

Solution 8 - Php

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.

Solution 9 - Php

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
)

Solution 10 - Php

use

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

Output:

array (
  0 => 'Sample array',
  1 => 
  array (
    0 => 'Apple',
    1 => 'Orange',
  ),
)

Solution 11 - Php

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.

Solution 12 - Php

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn Kar.View Question on Stackoverflow
Solution 1 - PhpkarllindmarkView Answer on Stackoverflow
Solution 2 - PhpFelix KlingView Answer on Stackoverflow
Solution 3 - PhpAdrian Cid AlmaguerView Answer on Stackoverflow
Solution 4 - PhpcutsoyView Answer on Stackoverflow
Solution 5 - PhpajrealView Answer on Stackoverflow
Solution 6 - PhpmakkusView Answer on Stackoverflow
Solution 7 - PhpRaphosView Answer on Stackoverflow
Solution 8 - PhptrincotView Answer on Stackoverflow
Solution 9 - PhpphoenixView Answer on Stackoverflow
Solution 10 - PhpKhaldoon MasudView Answer on Stackoverflow
Solution 11 - PhpDanialView Answer on Stackoverflow
Solution 12 - PhpAezaz DesaiView Answer on Stackoverflow