98 votes

json_decode à la classe personnalisée

Est-il possible de décoder une chaîne json vers un objet autre que stdClass ?

106voto

Michael McTiernan Points 2395

Pas automatiquement, mais vous pouvez le faire sur la route à l'ancienne.

$data = json_decode($json, true);

$class = new Whatever();
foreach ($data as $key => $value) $class->{$key} = $value;

Ou bien, vous pouvez rendre cela plus automatique :

class Whatever {
    public function set($data) {
        foreach ($data AS $key => $value) $this->{$key} = $value;
    }
}

$class = new Whatever();
$class->set($data);

Éditer : devenir un peu fancier :

class JSONObject {
    public function __construct($json = false) {
        if ($json) $this->set(json_decode($json, true));
    }

    public function set($data) {
        foreach ($data AS $key => $value) {
            if (is_array($value)) {
                $sub = new JSONObject;
                $sub->set($value);
                $value = $sub;
            }
            $this->{$key} = $value;
        }
    }
}

// These next steps aren't necessary. I'm just prepping test data.
$data = array(
    "this" => "that",
    "what" => "who",
    "how" => "dy",
    "multi" => array(
        "more" => "stuff"
    )
);
$jsonString = json_encode($data);

// Here's the sweetness.
$class = new JSONObject($jsonString);
print_r($class);

41voto

cweiske Points 13722

Nous avons construit JsonMapper pour mapper automatiquement les objets JSON sur nos propres classes de modèles. Il fonctionne bien avec les objets imbriqués/enfants.

Il ne s'appuie que sur les informations de type docblock pour le mappage, que la plupart des propriétés de classe ont de toute façon :

<?php
$mapper = new JsonMapper();
$contactObject = $mapper->map(
    json_decode(file_get_contents('http://example.org/contact.json')),
    new Contact()
);
?>

30voto

John Pettitt Points 183

Vous pouvez le faire - c'est un kludge mais tout à fait possible. Nous devions le faire quand nous avons commencé à stocker des choses dans couchbase.

$stdobj = json_decode($json_encoded_myClassInstance);  //JSON to stdClass
$temp = serialize($stdobj);                   //stdClass to serialized

// Now we reach in and change the class of the serialized object
$temp = preg_replace('@^O:8:"stdClass":@','O:7:"MyClass":',$temp);

// Unserialize and walk away like nothing happend
$myClassInstance = unserialize($temp);   // Presto a php Class 

Dans nos benchmarks, c'était beaucoup plus rapide que d'essayer d'itérer à travers toutes les variables de classe.

Caveat : ne fonctionne pas pour les objets imbriqués autres que stdClass

Éditer : gardez à l'esprit la source des données, il est fortement recommandé de ne pas faire cela avec les données non fiables des utilisateurs sans une analyse très soignée des risques.

17voto

Malachi Points 5733

Tu pourrais utiliser la bibliothèque de J Ohannes Schmitt.

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, 'MyNamespace\MyObject', 'json');

Dans la dernière version du sérialiseur JMS, la syntaxe est :

$serializer = SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, MyObject::class, 'json');

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