Частные члены класса 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