web-dev-qa-db-fra.com

Comment créer un tableau à partir de la sortie d'un tableau imprimé avec print_r?

J'ai un tableau:

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

et je fais:

print_r($a);

qui imprime:

Array ( [foo] => printme )

Y at-il une fonction, alors quand vous faites:

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

Je vais récupérer le tableau array('foo' => 'fooMe');?

38
John Kar.

J'ai en fait écrit une fonction qui analyse un "tableau chaîné" dans un tableau réel. Évidemment, c'est un peu hacky et tout le reste, mais cela fonctionne sur mon test. Voici un lien vers un prototype fonctionnel à http://codepad.org/idlXdij3 .

Je posterai aussi le code en ligne, pour ceux qui n'ont pas envie de cliquer sur le lien:

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

    }
?>
26
ninetwozero

Si vous souhaitez stocker un tableau sous forme de chaîne, utilisez serialize[docs] et unserialize[docs] .

Pour répondre à votre question: non, il n’existe pas de fonction intégrée pour analyser à nouveau la sortie de print_r dans un tableau.

14
Felix Kling

Non, mais vous pouvez utiliser les deux fonctions serialize et json_*.

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

$a = unserialize($input);

Ou:

echo json_encode($a);

$a = json_decode($input, true);
7
elslooo

Pour la sortie de tableau avec Subarrays, la solution fournie par ninetwozero ne fonctionnera pas, vous pouvez essayer avec cette fonction qui fonctionne avec des tableaux complexes:

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

?>

Il y a un petit bogue, si vous avez une valeur vide (chaîne vide), elle est incorporée dans la valeur auparavant.

7
Adrian Cid Almaguer

vous ne pouvez pas faire cela avec print_r,
var_export devrait permettre quelque chose de similaire, mais pas exactement ce que vous avez demandé

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

$val = var_export($a, true);
print_r($val);
eval('$func_val='.$val.';');
5
ajreal

Il y a un bel outil en ligne qui fait exactement ce que son nom est:

Convertisseur en ligne print_r to json

Depuis un objet JSON, créer un tableau avec le json_decode function n'est pas loin:

Pour obtenir un tableau à partir de cela, définissez le deuxième paramètre sur true. Si vous ne le faites pas, vous obtiendrez un objet à la place.

json_decode($jsondata, true);
2
makkus

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

Résultat: Array ( 0 => 'Sample array', 1 => Array ( 0 => 'Apple', 1 => 'Orange' ,), )

1
Khaldoon Masud

Fonction rapide (sans vérification si vous envoyez de bonnes données):

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

C'est l'entrée attendue:

Array
(
    [test] => 6
)
0
phoenix

Je pense que ma fonction est cool aussi, fonctionne avec des tableaux imbriqués:

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: il vaut mieux ne pas l'utiliser avec des données d'entrée utilisateur  

0
Raphos