php json_decode 到自定义类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5397758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
json_decode to custom class
提问by Tom
Is it possible to decode a json string to an object other than stdClass?
是否可以将 json 字符串解码为 stdClass 以外的对象?
回答by Michael McTiernan
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 could make that more automatic:
或者,您可以使其更加自动化:
class Whatever {
public function set($data) {
foreach ($data AS $key => $value) $this->{$key} = $value;
}
}
$class = new Whatever();
$class->set($data);
Edit: getting a little 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);
回答by cweiske
We built JsonMapperto map JSON objects onto our own model classes automatically. It works fine with nested/child objects.
我们构建了JsonMapper来自动将 JSON 对象映射到我们自己的模型类上。它适用于嵌套/子对象。
It only relies on docblock type information for mapping, which most class properties have anyway:
它只依赖于 docblock 类型信息进行映射,大多数类属性无论如何都具有:
<?php
$mapper = new JsonMapper();
$contactObject = $mapper->map(
json_decode(file_get_contents('http://example.org/contact.json')),
new Contact()
);
?>
回答by John Pettitt
You can do it - it's a kludge but totally possible. We had to do when we started storing things in 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
In our benchmarks this was way faster than trying to iterate through all the class variables.
在我们的基准测试中,这比尝试遍历所有类变量要快得多。
Caveat: Won't work for nested objects other than stdClass
警告:不适用于 stdClass 以外的嵌套对象
Edit: keep in mind the data source, it's strongly recommended that you don't do this withe untrusted data from users without a very carful analysis of the risks.
编辑:请记住数据源,强烈建议您不要在没有对风险进行非常仔细分析的情况下使用来自用户的不受信任的数据来执行此操作。
回答by Malachi
You could use Johannes Schmitt's 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:
在最新版本的 JMS 序列化程序中,语法是:
$serializer = SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, MyObject::class, 'json');
回答by Yevgeniy Afanasyev
You can make a wrapper for your object and make the wrapper look like it is the object itself. And it will work with multilevel 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
回答by jigarshahindia
You can do it in below way ..
您可以通过以下方式做到这一点..
<?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;
}
}
}
}
?>
?>
For more details visit create-custom-class-in-php-from-json-or-array
有关更多详细信息,请访问 create-custom-class-in-php-from-json-or-array
回答by Gordon
No, this is not possible as of PHP 5.5.1.
不,从 PHP 5.5.1 开始这是不可能的。
The only thing possible is to have json_decode
return associate arrays instead of the StdClass objects.
唯一可能的是json_decode
返回关联数组而不是 StdClass 对象。
回答by Francesco Terenzani
As Gordon says is not possible. But if you are looking for a way to obtain a string that can be decoded as an instance of a give class you can use serializeand unserialize instead.
正如戈登所说,这是不可能的。但是,如果您正在寻找一种方法来获取可以解码为给定类的实例的字符串,则可以改用序列化和反序列化。
class Foo
{
protected $bar = 'Hello World';
function getBar() {
return $this->bar;
}
}
$string = serialize(new Foo);
$foo = unserialize($string);
echo $foo->getBar();
回答by klawipo
I once created an abstract base class for this purpose. Let's call it JsonConvertible. It should serialize and deserialize the public members. This is possible using Reflection and late static binding.
我曾经为此目的创建了一个抽象基类。我们称之为 JsonConvertible。它应该序列化和反序列化公共成员。这可以使用反射和后期静态绑定来实现。
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 chance to make some properties ignored when serialized to/from json. I hope you get the idea, nonetheless.
仅凭记忆,所以可能不是完美无缺的。您还必须排除静态属性,并且可能会给派生类机会在序列化到 json 时忽略某些属性。尽管如此,我希望你能明白。
回答by ThiefMaster
JSON is a simple protocol to transfer data between various programming languages (and it's also a subset of JavaScript) which supports just certain types: numbers, strings, arrays/lists, objects/dicts. Objects are just key=value maps and Arrays are ordered lists.
JSON 是一种在各种编程语言(它也是 JavaScript 的一个子集)之间传输数据的简单协议,它只支持某些类型:数字、字符串、数组/列表、对象/字典。对象只是键=值映射,数组是有序列表。
So there is no way to express custom objects in a generic way. The solution is defining a structure where your program(s) will know that it's a custom object.
所以没有办法以通用的方式表达自定义对象。解决方案是定义一个结构,让您的程序知道它是一个自定义对象。
Here's an example:
下面是一个例子:
{ "cls": "MyClass", fields: { "a": 123, "foo": "bar" } }
This could be used to create an instance of MyClass
and set the fields a
and foo
to 123
and "bar"
.
这可以用来创建实例MyClass
,并设置领域a
和foo
以123
和"bar"
。