2011-03-22 70 views

回答

3

不,从PHP 5.5.1开始这是不可能的。

唯一可能的是让json_decode返回关联数组而不是StdClass对象。

0

正如戈登所说是不可能的。但是,如果你正在寻找一种方法来获得一个字符串,可以解码为一个给予类的实例,你可以使用serialize并反序列化。

class Foo 
{ 

    protected $bar = 'Hello World'; 

    function getBar() { 
     return $this->bar; 
    } 

} 

$string = serialize(new Foo); 

$foo = unserialize($string); 
echo $foo->getBar(); 
+0

这似乎没有解决这个问题。如果是这样,你必须提供一些解释。 – 2011-03-22 22:15:11

+0

我更好地解释了我的观点:P – 2011-03-22 22:35:11

70

不自动。但你可以做到这一点老式的路线。

$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); 
+0

我喜欢你的建议,只是为了说明它不适用于嵌套对象(STDClass或转换对象除外) – vivoconunxino 2016-11-09 10:45:31

-1

JSON是一个简单的协议,以各种之间传输数据编程语言(也是JavaScript的一个子集),它只支持某些类型:数字,字符串,数组/列表,对象/字典。对象只是键=值映射,而数组则是有序列表。

所以没有办法以通用的方式表达自定义对象。解决方案是定义一个结构,你的程序将知道它是一个自定义对象。

下面是一个例子:

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

这可以被用来创建MyClass一个实例,并afoo设置字段123"bar"

+4

这可能是真的,但问题不在于表示对象以通用的方式。这听起来像他有一个特定的JSON包,可以在一端或两端映射到特定的类。没有理由不能以这种方式使用JSON作为非泛型命名类的显式序列化。如果你想要一个通用的解决方案,就像你正在做的那样命名它是没有问题的,但是在JSON结构上签订商定合同也没什么问题。 – DougW 2013-03-27 20:50:22

20

你可以这样做 - 这是一个杂凑,但完全有可能。当我们开始将东西存储在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分析风险。

+0

这是否适用于封装的子类。例如。 '''{“a”:{“b”:“c”}}''','a'中的对象是另一个类,而不仅仅是一个关联数组? – 2014-05-15 18:28:13

+1

不,json_decode创建stdclass对象,包括子对象,如果你想让它们成为其他的东西,你必须像上面那样拼凑每个对象。 – 2014-05-15 23:29:21

+0

谢谢,这就是我想象中的 – 2014-05-21 18:16:16

14

我们建立了JsonMapper来将JSON对象自动映射到我们自己的模型类上。它适用于嵌套/子对象。

只依赖于映射文档块类型的信息,其中大部分类属性有反正:

<?php 
$mapper = new JsonMapper(); 
$contactObject = $mapper->map(
    json_decode(file_get_contents('http://example.org/contact.json')), 
    new Contact() 
); 
?> 
+0

很多thx为您的伟大的图书馆。 – 2017-05-03 20:07:02

+0

哇!这太神奇了。 – vothaison 2017-12-16 16:29:22

0

我曾经为此创建了一个抽象基类。我们称之为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序列化时忽略某些属性。尽管如此,我希望你明白这个主意。

0

你可以做下面的方式..

<?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

0

您可以包装为对象,使包装看起来像它是对象本身。它将与多级对象一起工作。

<?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