2012-05-05 2 views
1

Je suis en train de convertir la chaîne JSON dans un tableau en tableau,Conversion de json en tableau avec une méthode récursive?

$config = array(
    "type" => '{"category":"admin","page":"page"}', 
    "say"  => "Hello", 
    "php" => array(
     "say"  => "no", 
     "type" => '{"category":"admin","page":"page"}', 
     "gran" =>array(
      "name" => "Hi" 
     ) 
    ) 
); 

Mon code de travail,

class objectify 
{ 

    public function json_to_array($array, $recursive = true) 
    { 
     # if $array is not an array, let's make it array with one value of former $array. 
     if (!is_array($array)) $array = array($array); 

     foreach($array as $key => $value) 
     { 
      if($recursive === false) $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL) ? json_decode($value, true): $value; 
       else $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL) ? json_decode($value, true): is_array($value) ? self::json_to_array($array) : $value; 
     } 

     return $array; 
    } 
} 

Il fonctionne très bien sansméthode récursive mais les pauses quand je veux faire le récursive comme vous pouvez le voir dans mon code ci-dessus,

$object = new objectify(); 
$config = $object->json_to_array($config); 
print_r($config); 

message d'erreur,

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 2048 bytes) in C:\wamp\www\test\2012\php\set_variable.php on line 79 

Je veux juste obtenir ce résultat,

Array 
(
    [type] => Array 
     (
      [category] => admin 
      [page] => page 
     ) 
    [say] => Hello 
     (
      [say] => no 
      [type] => {"category":"admin","page":"page"} 
      [gran] => Array 
       (
        [name] => Hi 
       ) 

     ) 

) 

EDIT:

$config = 'type={"category":"admin","page":"page"}&text_editor={"name":"mce-basic"}&parent_id=self&subtitle=true&description=true&content_1=true&script_1=true&primary_image=true'; 
parse_str($config,$array); 
print_r($array); 
résultat

,

Array 
(
    [type] => {"category":"admin","page":"page"} 
    [text_editor] => {"name":"mce-basic"} 
    [parent_id] => self 
    [subtitle] => true 
    [description] => true 
    [content_1] => true 
    [script_1] => true 
    [primary_image] => true 
) 
+0

Puis-je demander à exactement pourquoi vous avez partiellement (et seulement partiellement) analysables JSON dans votre Structure de données? –

+0

Comment avez-vous obtenu un tableau de chaînes JSON en premier lieu? On dirait que ceux-ci devraient apparaître sous la forme d'un tableau JSON que vous pourriez simplement décoder tout à la fois. –

+0

Avez-vous besoin d'aide pour résoudre le problème de mémoire? –

Répondre

3

Solution rapide:

$full_array = array_map('json_decode', $array); 

Si tous vos paramètres sont JSON, et que vous voulez des tableaux réels au lieu de stdClass objets, vous pouvez avoir à faire:

function json_decode_array($input) { 
    $from_json = json_decode($input, true); 
    return $from_json ? $from_json : $input; 
} 
$full_array = array_map('json_decode_array', $array); 

Si vous avez plusieurs niveaux de tableaux imbriqués en dehors du JSON, alors vous devez faire votre propre récursivité. Essayez cette version de objecti:

class objectify 
{ 
    public function json_mapper($value, $recursive = true) { 
    if (!empty($value) && is_string($value) && 
     $decoded = json_decode($value, true)) { 
     return $decoded; 
    } elseif (is_array($value) && $recursive) { 
     return array_map('objectify::json_mapper', $value); 
    } else { 
     return $value; 
    } 
    } 

    // currying, anyone? 
    public function json_mapper_norecurse($value) { 
    return objectify::json_mapper($value, false); 
    } 

    public function json_to_array($array, $recursive = true) 
    { 
    # if $array is not an array, let's make it array with one value of 
    # former $array. 
    if (!is_array($array)) { 
     $array = array($array); 
    } 

    return array_map(
     $recursive ? 'objectify::json_mapper' 
       : 'objectify::json_mapper_norecurse', $array); 
    } 
} 

Ce qui fonctionne bien pour moi sur vos deux ensembles de données d'échantillon.

+0

Ceux-ci ne fonctionnent pas Mark, je viens de courir les deux. Les valeurs de chaîne JSON sont converties en chaînes vides. – PorridgeBear

+0

Hm. Mon résultat manquait les valeurs non-JSON - corrigées dans l'édition ci-dessus - mais semble autrement correct. Qu'est ce qui est different? –

+0

Ça a l'air bien, ne savait pas json_decode était récursif :) Def. la meilleure solution op. – PorridgeBear

0

Peut être fait beaucoup plus facilement.

function objectify(& $v, $k) { 
    $v_decoded = json_decode($v, true); 
    if ($v_decoded) { $v = $v_decoded; } 
} 

array_walk_recursive($config, 'objectify'); 
print_r($config); 

Array 
(
[type] => Array 
    (
     [category] => admin 
     [page] => page 
    ) 

[say] => Hello 
[php] => Array 
    (
     [say] => no 
     [type] => Array 
      (
       [category] => admin 
       [page] => page 
      ) 

     [gran] => Array 
      (
       [name] => Hi 
      ) 

    ) 

) 
+0

Vous n'avez pas besoin d'écrire votre propre récursivité, cependant; json_decode est déjà récursif. Donc, une fois que vous arrivez au JSON, vous êtes bon. –

+0

@Porridge - merci cela fonctionne parfaitement. mais comment puis-je appliquer 'array_walk_recursive ($ config, 'objectio');' dans une classe comme celle de mon OP? – laukok

2

En ce qui concerne votre code est concerné, il semble que vous ayez fait une erreur amenant à boucle pour toujours (dernière partie de la section récursive):

is_array($value) ? self::json_to_array($array) : $value; 

Vous nourrissez le tableau entier à la fonction récursive au lieu de la valeur testée pour être un tableau.

Changer à:

is_array($value) ? self::json_to_array($value) : $value; 

devrait résoudre cela.

Edit: Il semble que la condition ternaire imbriquée est à l'origine du problème, si vous mettez des accolades autour de la seconde, il fonctionne:

 else 
     { 
      $array[$key] = (!empty($value) && is_string($value) && json_decode($value) != NULL) 
           ? json_decode($value, true) 
           : (is_array($value) ? self::json_to_array($value) : $value); 
     } 

See the working example.

+0

merci mais toujours la même erreur 'Erreur fatale: La taille de la mémoire autorisée de 134217728 octets épuisés (a tenté d'allouer 523800 octets) dans C: \ wamp \ www \ test \ 2012 \ php \ set_variable.php sur la ligne 79' – laukok

+0

Dans les fonctions plutôt que votre propre récursivité, ils sont beaucoup plus performants. – PorridgeBear

+0

@lauthiamkok Je ne trouve pas la source, mais j'ai lu quelque part que les opérateurs ternaires imbriqués peuvent provoquer des résultats inattendus. Cela change-t-il quelque chose si vous mettez des parenthèses autour de cette dernière section (celle que j'ai publiée)? – jeroen

0

Peut-être que vous pouvez utiliser la fonction facile:

$array = json_decode(json_encode($object), true); 

Trouvé ici: https://gist.github.com/victorbstan/744478

setTimeout(function() { alert("JavaScript"); }, 1000);