Дважды щелкните файл Package.appxmanifest в своем проекте. Перейдите на вкладку «Возможности». Добавьте в свой проект функцию Private Networks.
Короткий ответ: Нет (не, что я знаю о*)
ответ 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 (), но мои тесты показали их, чтобы быть погоней за несбыточным.
Вы могли создать какой-то FactoryClass:
function create(array $data)
{
$user = new User();
foreach($data as $k => $v) {
$user->$k = $v;
}
return $user;
}
Это не похоже на решение, которое Вы хотели, но это сделало Ваше задание.
Я думаю лучший способ обработать, это было бы через конструктора, или непосредственно или через фабрику:
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));
}
}
Для ответа на прямой вопрос, нет, существует, не должен был сделать это с 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;
}
, я не протестировал это, но я надеюсь, что это объясняет идею. Идеально, все Ваши объекты должны расшириться от некоторого базового объекта (обычно названный "объектом класса"), таким образом, можно добавить этот код в одном месте только.
Я знаю, что JSON не поддерживает сериализацию функций, которая совершенно приемлема, и даже желаемая. Мои классы в настоящее время используются в качестве объектов значения в общении с JavaScript, и функции не содержали бы значения (и регулярные функции сериализации не применимы).
Однако, поскольку функциональность, имеющая отношение к этим увеличениям классов, инкапсулируя их служебные функции (такие как сохранение Пользователя () в этом случае) в фактическом классе, имеет смысл мне. Это означает, что они больше не строго объекты значения, хотя, и это - то, где я сталкиваюсь со своей вышеупомянутой проблемой.
идее, которую я имел, определят имя класса в строке JSON и вероятно закончилась бы как это:
$string = '{"name": "testUser", "password": "testPassword", "class": "User"}';
$object = json_decode ($string);
$user = ($user->class) $object;
И реверс установил бы свойство класса json_encode during/after. Я знаю, немного замысловатый, но я просто пытаюсь держать связанный код вместе. Я, вероятно, закончу тем, что вынул свои служебные функции из классов снова; измененный подход конструктора кажется немного непрозрачным и сталкивается с проблемой с вложенными объектами.
я действительно ценю это и любую будущую обратную связь, как бы то ни было.
Должен сказать, я немного встревожен тем, что это не просто стандартная готовая функциональность какой-то библиотеки, если не самого JSON. Почему не вы хотите, чтобы с обеих сторон были по существу похожие объекты? (Во всяком случае, насколько позволяет JSON)
Я что-то здесь упускаю? Есть ли библиотека, которая этим занимается? (AFAICT, ни один из [thrift, protocol buffers, avro] на самом деле не имеет API для javascript. Что касается моей проблемы, меня больше всего интересует JS <-> PHP, отчасти также JS <-> python.)
{{1 }}