How create an array from the output of an array pr

2019-01-01 11:03发布

问题:

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?

回答1:

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

    }
?>


回答2:

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.



回答3:

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


回答4:

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.



回答5:

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


回答6:

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


回答7:

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
)


回答8:

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



回答9:

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

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