2011-03-22 43 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