[php] json_decode를 사용자 정의 클래스로

json 문자열을 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);


답변

JSON 객체를 자체 모델 클래스에 자동으로 매핑하기 위해 JsonMapper 를 구축 했습니다 . 중첩 / 자식 개체와 잘 작동합니다.

대부분의 클래스 속성은 어쨌든 매핑을 위해 docblock 유형 정보에만 의존합니다.

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


답변

당신은 그것을 할 수 있습니다-그것은 kludge이지만 완전히 가능합니다. 소파베이스에 물건을 보관하기 시작했을 때해야 했어요.

$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 

벤치 마크에서 이것은 모든 클래스 변수를 반복하는 것보다 훨씬 빠릅니다.

주의 사항 : stdClass 이외의 중첩 된 개체에 대해서는 작동하지 않습니다.

편집 : 데이터 소스를 염두에 두십시오. 위험에 대한 세심한 분석 없이는 사용자의 신뢰할 수없는 데이터와 함께이 작업을 수행하지 않는 것이 좋습니다.


답변

J ohannes Schmitt의 Serializer 라이브러리를 사용할 수 있습니다 .

$serializer = JMS\Serializer\SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, 'MyNamespace\MyObject', 'json');

최신 버전의 JMS 직렬 변환기에서 구문은 다음과 같습니다.

$serializer = SerializerBuilder::create()->build();
$object = $serializer->deserialize($jsonData, MyObject::class, 'json');


답변

개체에 대한 래퍼를 만들고 래퍼를 개체 자체처럼 보이게 만들 수 있습니다. 그리고 그것은 다단계 개체와 함께 작동합니다.

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


답변

아니요, PHP 5.5.1부터는 불가능합니다.

가능한 유일한 방법 json_decode은 StdClass 객체 대신에 연관 배열 을 반환하는 것입니다.


답변

아래 방법으로 할 수 있습니다 ..

<?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를 방문하십시오.