Частные члены класса PHP json_encode

Я пытаюсь JSON закодировать некоторые объекты в PHP, но мне грозит проблема: я хочу кодировать данные, которые хранятся у частных членов класса. Я нашел этот кусок кода для кодирования этого объекта, вызвав функцию кодирования, например:

public function encodeJSON() 
{ 
    foreach ($this as $key => $value) 
    { 
        $json->$key = $value; 
    } 
    return json_encode($json); 
}

Однако это работает только в том случае, если объект, который я хочу кодировать, не содержит других объектов внутри, что и происходит. Как я могу сделать, чтобы кодировать не только "внешний" объект, но и кодировать также все элементы, которые тоже являются объектами?

Ответ 1

Лучший способ сериализации объекта с частными свойствами - реализовать интерфейс \JsonSerializable, а затем реализовать собственный метод JsonSerialize, чтобы вернуть требуемые данные для сериализации.

<?php

class Item implements \JsonSerializable
{
    private $var;
    private $var1;
    private $var2;

    public function __construct()
    {
        // ...
    }

    public function jsonSerialize()
    {
        $vars = get_object_vars($this);

        return $vars;
    }
}

json_encode теперь будет правильно сериализовать ваш объект.

Ответ 2

Если вы используете php 5.4, вы можете использовать интерфейс JsonSerializable: http://www.php.net/manual/en/class.jsonserializable.php

Вы просто реализуете метод jsonSerialize в своем классе, который возвращает все, что вы хотите закодировать.

Затем, когда вы передаете свой объект в json_encode, он закодирует результат jsonSerialize.

Ответ 3

В любом случае. Вам нужно создать общедоступный метод в вашем классе, чтобы вернуть все поля json encoded

public function getJSONEncode() {
    return json_encode(get_object_vars($this));
}

Ответ 4

Я думаю, что @Petah получил лучший подход, но таким образом вы теряете свойства, которые являются массивом или объектом. Поэтому я добавил функцию, которая рекурсивно рекурсивно:

function json_encode_private($object) {

    function extract_props($object) {
        $public = [];

        $reflection = new ReflectionClass(get_class($object));

        foreach ($reflection->getProperties() as $property) {
            $property->setAccessible(true);

            $value = $property->getValue($object);
            $name = $property->getName();

            if(is_array($value)) {
                $public[$name] = [];

                foreach ($value as $item) {
                    if (is_object($item)) {
                        $itemArray = extract_props($item);
                        $public[$name][] = $itemArray;
                    } else {
                        $public[$name][] = $item;
                    }
                }
            } else if(is_object($value)) {
                $public[$name] = extract_props($value);
            } else $public[$name] = $value;
        }

        return $public;
    }

    return json_encode(extract_props($object));
}

EDIT: Добавлена ​​проверка is_object() внутри цикла массива, чтобы избежать исключения get_class() в следующем вызове extract_props(), когда элементы массива не являются объектами, такими как строки или числа.

Ответ 5

public function jsonSerialize()
{
    $objectArray = [];
    foreach($this as $key => $value) {
        $objectArray[$key] = $value;
    }

    return json_encode($objectArray);
}

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

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

Ответ 6

Это будет печатать JSON со всеми свойствами (public, private и protected) класса foo:

$reflection = new ReflectionClass('Foo');
$properties = $reflection->getdefaultProperties();

echo json_encode($properties);

Это будет работать из любого контекста.

Ответ 7

Используя отражение, вы можете json_encode частные свойства, хотя его не считается лучшей практикой:

function json_encode_private($object) {
    $public = [];
    $reflection = new ReflectionClass($object);
    foreach ($reflection->getProperties() as $property) {
        $property->setAccessible(true);
        $public[$property->getName()] = $property->getValue($object);
    }
    return json_encode($public);
}

например.

class Foo {
    public $a = 1;
    public $b = 2;
}
class Bar {
    private $c = 3;
    private $d = 4;
}

var_dump(json_encode(new Foo()));
var_dump(json_encode_private(new Bar()));

Выходы:

string(13) "{"a":1,"b":2}"
string(13) "{"c":3,"d":4}"

http://codepad.viper-7.com/nCcKYW

Ответ 8

Вы можете кодировать только частные члены объекта из класса. Однако, как примечание, функция json_enocde не работает для вас? http://php.net/manual/en/function.json-encode.php