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

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

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

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

Лучший способ сериализации объекта с частными свойствами – реализовать интерфейс \ 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 будет сериализовать ваш объект правильно.

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

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

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

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

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

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

 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 (), когда элементы массива не являются объектами, такими как строки или числа.

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

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

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

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

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

Это будет работать в любом контексте.

Используя отражение, вы можете использовать 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

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