json_decode到自定义类
是否有可能解码一个JSONstring的对象以外的stdClass?
不自动。 但是,你可以做到这一点老式的路线。
$data = json_decode($json, true); $class = new Whatever(); foreach ($data as $key => $value) $class->{$key} = $value;
或者,也可以使其更自动:
class Whatever { public function set($data) { foreach ($data AS $key => $value) $this->{$key} = $value; } } $class = new Whatever(); $class->set($data);
编辑 :得到一点发烧友:
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);
你可以做到这一点 – 这是一个kludge,但完全有可能。 当我们开始在couchbase中存储东西时,我们必须做。
$stdobj = json_decode($json_encoded_myClassInstance); //JSON to stdClass $temp = serialize($stdobj); //stdClass to serialized
//现在我们进入并更改序列化对象的类
$temp = preg_replace('@^O:8:"stdClass":@','O:7:"MyClass":',$temp);
//反序列化,像没有任何事情一样走开
$myClassInstance = unserialize($temp); // Presto a php Class
在我们的基准testing中,这比通过遍历所有类variables要快得多。
警告:除了stdClass之外,不能用于嵌套对象
编辑:记住数据源,强烈build议您不要对用户的不可信数据做这样的事情,而不要对这些风险进行非常仔细的分析。
我们构build了JsonMapper ,将JSON对象自动映射到我们自己的模型类上。 它适用于嵌套/子对象。
它只依靠docblocktypes信息进行映射,而大多数类属性都有:
<?php $mapper = new JsonMapper(); $contactObject = $mapper->map( json_decode(file_get_contents('http://example.org/contact.json')), new Contact() ); ?>
你可以使用J ohannes Schmitt的Serializer库 。
$serializer = JMS\Serializer\SerializerBuilder::create()->build(); $object = $serializer->deserialize($jsonData, 'MyNamespace\MyObject', 'json');
不,从PHP 5.5.1开始这是不可能的。
唯一可能的是让json_decode
返回关联数组而不是StdClass对象。
正如戈登所说是不可能的。 但是,如果你正在寻找一种方法来获得一个string,可以解码为一个给予类的实例,你可以使用序列化和反序列化。
class Foo { protected $bar = 'Hello World'; function getBar() { return $this->bar; } } $string = serialize(new Foo); $foo = unserialize($string); echo $foo->getBar();
我曾经为此创build了一个抽象基类。 我们称之为JsonConvertible。 它应该对公众成员进行序列化和反序列化。 这是可能的使用reflection和晚静态绑定。
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();
只是从记忆,所以可能不完美。 你也将不得不排除静态属性,并可能给派生类的机会,使一些属性忽略序列化/从JSON时。 尽pipe如此,我希望你明白这个主意。
你可以用下面的方法做
<?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; } } } }
?>
有关更多详细信息,请访问create-custom-class-in-php-from-json-or-array
你可以为你的对象制作一个包装器,并使包装器看起来像是对象本身。 它将与多级对象一起工作。
<?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
JSON是一种在各种编程语言之间传递数据的简单协议(也是JavaScript的一个子集),它只支持某些types:数字,string,数组/列表,对象/字典。 对象只是键=值映射,数组是有序的列表。
所以没有办法以通用的方式表示自定义对象。 解决scheme是定义一个你的程序将知道它是一个自定义对象的结构。
这是一个例子:
{ "cls": "MyClass", fields: { "a": 123, "foo": "bar" } }
这可以用来创buildMyClass
的实例,并将字段a
和foo
为123
和"bar"
。