52 votes

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 le fais :

print_r($a);

qui imprime :

Array ( [foo] => printme )

Y a-t-il une fonction, alors quand on fait :

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

Je vais obtenir le tableau array('foo' => 'fooMe'); de retour ?

0 votes

Afin d'ajouter un contexte supplémentaire au "pourquoi", j'ai rencontré ce même problème. Un développeur précédent a laissé derrière lui un code qui analysait les données d'une autre plateforme et enregistrait les résultats sous forme de chaînes print_r (parce qu'elles étaient faciles à lire). Quelque temps plus tard, le besoin de ré-analyser ces informations s'est fait sentir, et la seule trace en était les journaux.

0 votes

0 votes

@kodmanyagha cette page ne traite pas les sous-réseaux (besoin d'un appel récursif lors d'une réunion Array( ), ni avec des cas particuliers. Quoi qu'il en soit, le résultat de print_r() est non-déterministe car la clé/valeur peut contenir les séparateurs utilisés par imprimer_r o \n et rien ne nous échappe...

33voto

ninetwozero Points 4077

J'ai écrit une fonction qui analyse un "stringed array" en un tableau réel. Évidemment, c'est un peu bricolé et tout ça, mais ça fonctionne sur mon testcase. Voici un lien vers un prototype fonctionnel à l'adresse suivante http://codepad.org/idlXdij3 .

Je vais également afficher le code en ligne, pour les personnes 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;
        }

    }
?>

0 votes

Cela ne fonctionne pas très bien - il supprime les espaces dans la clé et la valeur ! codepad.org/GYL4M2xi

0 votes

@Elias J'ai mis à jour le script ci-dessus, je ne me souviens plus trop pourquoi je remplaçais les espaces. Voici un lien vers une version révisée (basée sur votre code) : codepad.org/od79B28T

17 votes

Pour les tableaux simples, cela fonctionne, mais pour les tableaux multidimensionnels, cela échoue. Il suffit d'utiliser este .

14voto

Felix Kling Points 247451

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

Pour répondre à votre question : Non, il n'y a pas de fonction intégrée pour analyser la sortie de l'application print_r dans un tableau à nouveau.

2 votes

Cette réponse évite d'apporter une solution à la question posée. Nous devons supposer que le PO (et les autres chercheurs qui trouvent cette page) ne sont pas en mesure de modifier la structure d'entrée. (S'ils pouvaient modifier la structure d'entrée, il y a beaucoup d'autres pages sur SO qui décrivent comment utiliser serialize / unserialize y json_encode() / json_decode() .)

11voto

Pour la sortie de tableaux avec des sous-réseaux, 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 bug, si vous avez une valeur vide (chaîne vide), elle est incorporée dans la valeur précédente.

0 votes

Une solution rapide pour résoudre le problème des chaînes vides. Au tout début de la fonction, ajoutez cette ligne de code : $output = str_replace('] => '." \n ", '] => [[[CHAÎNE VIDE]]]'." \n ", $output) ; Ensuite, directement avant la ligne de code existante "$topArray[$key] = $element ;", ajoutez cette ligne : $element = str_replace('[[[EMPTYSTRING]]]', '', $element) ;

0 votes

Outre le problème des valeurs vides, il ne traite pas non plus les chaînes vides. clés et ne prend pas en charge stdClass Object .

8voto

Tim Points 5911

Non. Mais vous pouvez utiliser les deux serialize y json_* fonctions.

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

$a = unserialize($input);

Ou :

echo json_encode($a);

$a = json_decode($input, true);

1 votes

Le PO ne demande pas d'autres moyens d'encoder/de sérialiser les données. L'OP a déclaré que l'entrée est la sortie de print_r() et ce texte doit être analysé.

7voto

ajreal Points 31456

Vous ne pouvez pas le faire 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.';');

1 votes

Et qu'est-ce que needed_function dans cette affaire ?

0 votes

C'est ce que l'OP a posté... needed_function(' Array ( [foo] => printme )');

2 votes

Je pense qu'il voulait savoir ce que serait cette fonction pour qu'on lui renvoie un tableau.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X