Est-il possible de décoder une chaîne json vers un objet autre que stdClass ?
Réponses
Trop de publicités?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);
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()
);
?>
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.
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');