Json_decode for custom class

Is it possible to decode a json string for an object other than stdClass?

+71
json php
Mar 22 '11 at 20:59
source share
11 answers

Not automatically. But you can do it the old fashioned route.

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

Or, alternatively, you can make it more automatic:

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

Edit : get involved a bit:

 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 the sweetness. $class = new JSONObject($jsonString); print_r($class); 
+84
Mar 22 2018-11-21T00:
source share

You can do it - this is a flowerbed, but it is possible. We should have done when we started storing things on the couch.

 $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 

In our tests, this was much faster than trying to iterate over all the class variables.

Caution: will not work for nested objects other than stdClass

Change: keep in mind the source of the data, it is highly recommended that you do not do this with unreliable data from users without a thorough risk analysis.

+24
Dec 18 '13 at 9:30
source share

We built JsonMapper to automatically map JSON objects on our own model classes. It works great with nested / child objects.

It uses only information of type docblock type for matching, which has most of the properties of the class:

 <?php $mapper = new JsonMapper(); $contactObject = $mapper->map( json_decode(file_get_contents('http://example.org/contact.json')), new Contact() ); ?> 
+21
Jan 27 '14 at
source share

You can use the J ohannes Schmitt Serializer library .

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

In the latest version of the JMS serializer, the syntax is:

 $serializer = SerializerBuilder::create()->build(); $object = $serializer->deserialize($jsonData, MyObject::class, 'json'); 
+11
Jan 19 '15 at 16:58
source share

No, this is not possible with PHP 5.5.1.

The only possible way is json_decode return associated arrays instead of StdClass objects.

+3
Mar 22 '11 at 20:59
source share

You can create a wrapper for your object and make the shell look like the object itself. And it will work with multi-level objects.

 <?php class Obj { public $slave; public function __get($key) { return property_exists ( $this->slave , $key ) ? $this->slave->{$key} : null; } public function __construct(stdClass $slave) { $this->slave = $slave; } } $std = json_decode('{"s3":{"s2":{"s1":777}}}'); $o = new Obj($std); echo $o->s3->s2->s1; // you will have 777 
+3
Aug 24 '16 at 7:26
source share

You can do it below.

 <?php class CatalogProduct { public $product_id; public $sku; public $name; public $set; public $type; public $category_ids; public $website_ids; function __construct(array $data) { foreach($data as $key => $val) { if(property_exists(__CLASS__,$key)) { $this->$key = $val; } } } } 

? >

Read more create-custom-class-in-php-from-json-or-array

+1
Aug 18 '16 at 14:24
source share

As Gordon says, this is not possible. But if you are looking for a way to get a string that can be decoded as an instance of a class, you can use serialize and unserialize instead.

 class Foo { protected $bar = 'Hello World'; function getBar() { return $this->bar; } } $string = serialize(new Foo); $foo = unserialize($string); echo $foo->getBar(); 
0
Mar 22 2018-11-21T00:
source share

I once created a base base class for this purpose. Let me call him JsonConvertible. It must serialize and deserialize public members. This is possible using Reflection and late static binding.

 abstract class JsonConvertible { static function fromJson($json) { $result = new static(); $objJson = json_decode($json); $class = new \ReflectionClass($result); $publicProps = $class->getProperties(\ReflectionProperty::IS_PUBLIC); foreach ($publicProps as $prop) { $propName = $prop->name; if (isset($objJson->$propName) { $prop->setValue($result, $objJson->$propName); } else { $prop->setValue($result, null); } } return $result; } function toJson() { return json_encode($this); } } class MyClass extends JsonConvertible { public $name; public $whatever; } $mine = MyClass::fromJson('{"name": "My Name", "whatever": "Whatever"}'); echo $mine->toJson(); 

Just from memory, so probably not flawless. You will also have to exclude static properties and may give derived classes the ability to ignore some properties when serializing to / from json. Hope you get this idea nonetheless.

0
Dec 03 '15 at 11:53 on
source share

I think the easiest way is:

 function mapJSON($json, $class){ $decoded_object = json_decode($json); foreach ($decoded_object as $key => $value) { $class->$key = $value; } return $class;} 
0
Jul 23 '19 at 9:31
source share

JSON is a simple protocol for transferring data between different programming languages ​​(as well as a subset of JavaScript), which supports only certain types: numbers, strings, arrays / lists, objects / dicts. Objects are just keys = values, and arrays are ordered lists.

Thus, it is not possible to express user objects in a general way. The solution determines the structure in which your program will know that it is a user object.

Here is an example:

 { "cls": "MyClass", fields: { "a": 123, "foo": "bar" } } 

This can be used to create an instance of MyClass and set the fields a and foo to 123 and "bar" .

-one
Mar 22 2018-11-22T00:
source share



All Articles