Десериализация от JSON в PHP, с кастингом?

Дважды щелкните файл Package.appxmanifest в своем проекте. Перейдите на вкладку «Возможности». Добавьте в свой проект функцию Private Networks.

19
задан Jeroen van Delft 18 March 2009 в 14:25
поделиться

6 ответов

Короткий ответ: Нет (не, что я знаю о*)

ответ Long: json_encode только сериализирует общедоступные переменные. Как Вы видите на спецификация JSON, нет никакого "функционального" типа данных. Это оба причины, почему Ваши методы не сериализируются в Ваш объект JSON.

Ryan Graham прав - единственный способ воссоздать эти объекты как non-stdClass экземпляры состоит в том, чтобы воссоздать их постдесериализация.

Пример

<?php

class Person
{
    public $firstName;
    public $lastName;

    public function __construct( $firstName, $lastName )
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
    }

    public static function createFromJson( $jsonString )
    {
        $object = json_decode( $jsonString );
        return new self( $object->firstName, $object->lastName );
    }

    public function getName()
    {
        return $this->firstName . ' ' . $this->lastName;
    }
}

$p = new Person( 'Peter', 'Bailey' );
$jsonPerson = json_encode( $p );

$reconstructedPerson = Person::createFromJson( $jsonPerson );

echo $reconstructedPerson->getName();

, С другой стороны, если Вам действительно не нужны данные как JSON, можно просто использовать нормальная сериализация и усилить __ сон () и __ пробуждение () рычаги для достижения дополнительной настройки.

* В предыдущий вопрос моего собственного было предложено, чтобы Вы могли реализовать некоторые интерфейсы SPL для настройки ввода/вывода json_encode (), но мои тесты показали их, чтобы быть погоней за несбыточным.

9
ответ дан 30 November 2019 в 03:16
поделиться

Вы могли создать какой-то FactoryClass:

function create(array $data)  
{
    $user = new User();
    foreach($data as $k => $v) {
        $user->$k = $v;
    }
    return $user;
}

Это не похоже на решение, которое Вы хотели, но это сделало Ваше задание.

3
ответ дан 30 November 2019 в 03:16
поделиться

Я думаю лучший способ обработать, это было бы через конструктора, или непосредственно или через фабрику:

class User
{
   public $username;
   public $nestedObj; //another class that has a constructor for handling json
   ...

   // This could be make private if the factories below are used exclusively
   // and then make more sane constructors like:
   //     __construct($username, $password)
   public function __construct($mixed)
   {
       if (is_object($mixed)) {
           if (isset($mixed->username))
               $this->username = $mixed->username;
           if (isset($mixed->nestedObj) && is_object($mixed->nestedObj))
               $this->nestedObj = new NestedObject($mixed->nestedObj);
           ...
       } else if (is_array($mixed)) {
           if (isset($mixed['username']))
               $this->username = $mixed['username'];
           if (isset($mixed['nestedObj']) && is_array($mixed['nestedObj']))
               $this->nestedObj = new NestedObj($mixed['nestedObj']);
           ...
       }
   }
   ...

   public static fromJSON_by_obj($json)
   {
       return new self(json_decode($json));
   }

   public static fromJSON_by_ary($json)
   {
       return new self(json_decode($json, TRUE)); 
   }
}
9
ответ дан 30 November 2019 в 03:16
поделиться

Для ответа на прямой вопрос, нет, существует, не должен был сделать это с json_encode/json_decode. JSON был разработан и определен, чтобы быть форматом для кодирования информации, а не для сериализации объектов. Функция PHP не идет кроме того.

, Если Вы интересуетесь воссозданием объектов от JSON, одно возможное решение является статическим методом для всех объектов в Вашей иерархии, которая принимает stdClass/string и заполняет переменные, который выглядит примерно так

//semi pseudo code, not tested
static public function createFromJson($json){
    //if you pass in a string, decode it to an object
    $json = is_string($json) ? json_decode($json) : $json;

    foreach($json as $key=>$value){
        $object = new self();
        if(is_object($value)){
            $object->{$key} = parent::createFromJson($json);
        }
        else{
            $object->{$key} = $value;
        }
    }

    return $object;
}

, я не протестировал это, но я надеюсь, что это объясняет идею. Идеально, все Ваши объекты должны расшириться от некоторого базового объекта (обычно названный "объектом класса"), таким образом, можно добавить этот код в одном месте только.

0
ответ дан 30 November 2019 в 03:16
поделиться

Я знаю, что JSON не поддерживает сериализацию функций, которая совершенно приемлема, и даже желаемая. Мои классы в настоящее время используются в качестве объектов значения в общении с JavaScript, и функции не содержали бы значения (и регулярные функции сериализации не применимы).

Однако, поскольку функциональность, имеющая отношение к этим увеличениям классов, инкапсулируя их служебные функции (такие как сохранение Пользователя () в этом случае) в фактическом классе, имеет смысл мне. Это означает, что они больше не строго объекты значения, хотя, и это - то, где я сталкиваюсь со своей вышеупомянутой проблемой.

идее, которую я имел, определят имя класса в строке JSON и вероятно закончилась бы как это:

$string = '{"name": "testUser", "password": "testPassword", "class": "User"}';
$object = json_decode ($string);
$user = ($user->class) $object;

И реверс установил бы свойство класса json_encode during/after. Я знаю, немного замысловатый, но я просто пытаюсь держать связанный код вместе. Я, вероятно, закончу тем, что вынул свои служебные функции из классов снова; измененный подход конструктора кажется немного непрозрачным и сталкивается с проблемой с вложенными объектами.

я действительно ценю это и любую будущую обратную связь, как бы то ни было.

1
ответ дан 30 November 2019 в 03:16
поделиться

Должен сказать, я немного встревожен тем, что это не просто стандартная готовая функциональность какой-то библиотеки, если не самого JSON. Почему не вы хотите, чтобы с обеих сторон были по существу похожие объекты? (Во всяком случае, насколько позволяет JSON)

Я что-то здесь упускаю? Есть ли библиотека, которая этим занимается? (AFAICT, ни один из [thrift, protocol buffers, avro] на самом деле не имеет API для javascript. Что касается моей проблемы, меня больше всего интересует JS <-> PHP, отчасти также JS <-> python.)

{{1 }}
-1
ответ дан 30 November 2019 в 03:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: