是否有可能将json字符串解码为stdClass以外的对象?json_decode到自定义类
回答
不,从PHP 5.5.1开始这是不可能的。
唯一可能的是让json_decode
返回关联数组而不是StdClass对象。
正如戈登所说是不可能的。但是,如果你正在寻找一种方法来获得一个字符串,可以解码为一个给予类的实例,你可以使用serialize并反序列化。
class Foo
{
protected $bar = 'Hello World';
function getBar() {
return $this->bar;
}
}
$string = serialize(new Foo);
$foo = unserialize($string);
echo $foo->getBar();
不自动。但你可以做到这一点老式的路线。
$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);
我喜欢你的建议,只是为了说明它不适用于嵌套对象(STDClass或转换对象除外) – vivoconunxino 2016-11-09 10:45:31
JSON是一个简单的协议,以各种之间传输数据编程语言(也是JavaScript的一个子集),它只支持某些类型:数字,字符串,数组/列表,对象/字典。对象只是键=值映射,而数组则是有序列表。
所以没有办法以通用的方式表达自定义对象。解决方案是定义一个结构,你的程序将知道它是一个自定义对象。
下面是一个例子:
{ "cls": "MyClass", fields: { "a": 123, "foo": "bar" } }
这可以被用来创建MyClass
一个实例,并a
和foo
设置字段123
和"bar"
。
这可能是真的,但问题不在于表示对象以通用的方式。这听起来像他有一个特定的JSON包,可以在一端或两端映射到特定的类。没有理由不能以这种方式使用JSON作为非泛型命名类的显式序列化。如果你想要一个通用的解决方案,就像你正在做的那样命名它是没有问题的,但是在JSON结构上签订商定合同也没什么问题。 – DougW 2013-03-27 20:50:22
你可以这样做 - 这是一个杂凑,但完全有可能。当我们开始将东西存储在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);
//反序列化的走开像什么happend
$myClassInstance = unserialize($temp); // Presto a php Class
在我们的测试,这是方式比尝试遍历所有类变量更快。
警告:会不会比其他stdClass已经嵌套对象工作
编辑:牢记数据源,我们强烈建议你不要这样做枝条从用户不可信数据没有非常carful分析风险。
这是否适用于封装的子类。例如。 '''{“a”:{“b”:“c”}}''','a'中的对象是另一个类,而不仅仅是一个关联数组? – 2014-05-15 18:28:13
不,json_decode创建stdclass对象,包括子对象,如果你想让它们成为其他的东西,你必须像上面那样拼凑每个对象。 – 2014-05-15 23:29:21
谢谢,这就是我想象中的 – 2014-05-21 18:16:16
我们建立了JsonMapper来将JSON对象自动映射到我们自己的模型类上。它适用于嵌套/子对象。
只依赖于映射文档块类型的信息,其中大部分类属性有反正:
<?php
$mapper = new JsonMapper();
$contactObject = $mapper->map(
json_decode(file_get_contents('http://example.org/contact.json')),
new Contact()
);
?>
很多thx为您的伟大的图书馆。 – 2017-05-03 20:07:02
哇!这太神奇了。 – vothaison 2017-12-16 16:29:22
你可以使用Ĵohannes Schmitt's Serializer library。
$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, 'MyNamespace\MyObject', 'json');
我曾经为此创建了一个抽象基类。我们称之为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序列化时忽略某些属性。尽管如此,我希望你明白这个主意。
你可以做下面的方式..
<?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
- 1. php json_decode,opencart自定义字段
- 2. 自定义操作不绑定到自定义内容类型
- 3. 将类投射到自定义类
- 4. 自动添加自定义分类到自定义文章类型
- 5. MVC - >绑定到自定义类型
- 6. Android ListView绑定到自定义类
- 7. 绑定到自定义类上的DependencyProperty
- 8. WPF ListView绑定到自定义类
- 9. json_encode和json_decode自定义php api不返回json字符串
- 10. php - json_decode未定义索引,但值是
- 11. json_decode之后的未定义索引
- 12. 自定义类=自定义+分配,自定义+初始化
- 13. 获取来自json_decode
- 14. 获取来自json_decode()
- 15. 绑定自定义类从自定义类
- 16. 固定链接自定义类型后与自定义分类
- 17. 添加自定义属性到自定义类和初始化类
- 18. 自定义ArrayList类
- 19. 自定义DataControlField类
- 20. 自定义ClickHandler类
- 21. 自定义类C#
- 22. 自定义App类
- 23. 自定义SharedPreferences类
- 24. Pimcore自定义类
- 25. 从自定义类
- 26. json_decode保存类型
- 27. json_decode到数组?
- 28. 得到与json_decode
- 29. Cin参数到自定义类
- 30. deserialise XML响应到自定义类
这似乎没有解决这个问题。如果是这样,你必须提供一些解释。 – 2011-03-22 22:15:11
我更好地解释了我的观点:P – 2011-03-22 22:35:11