47 votes

Membres privés de la classe PHP json_encode

J'essaie d'encoder en JSON certains objets en PHP, mais je suis confronté à un problème : je veux encoder des données qui sont conservées par une classe de membres privés. J'ai trouvé ce morceau de code pour encoder cet objet en appelant une fonction d'encodage comme :

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

Cependant, cela ne fonctionne que si l'objet que je veux encoder ne contient pas d'autres objets à l'intérieur, ce qui est le cas. Comment puis-je faire pour encoder non seulement l'objet "extérieur", mais également encoder tous les membres qui sont également des objets ?

100voto

samsamm777 Points 1450

La meilleure méthode pour sérialiser un objet avec des propriétés privées consiste à implémenter l'interface \JsonSerializable, puis à implémenter votre propre méthode JsonSerialize pour renvoyer les données dont vous avez besoin pour être sérialisées.

 <?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 sérialisera désormais correctement votre objet.

37voto

lucas Points 559

Si vous utilisez php 5.4, vous pouvez utiliser l'interface JsonSerializable : http://www.php.net/manual/en/class.jsonserializable.php

Vous implémentez simplement une méthode jsonSerialize dans votre classe qui renvoie tout ce que vous voulez encoder.

Ensuite, lorsque vous passez votre objet dans json_encode, il codera le résultat de jsonSerialize.

14voto

Andre Medeiros Points 21

Je pense que @Petah a la meilleure approche, mais de cette façon, vous perdez les propriétés qui sont un tableau ou un objet. J'ai donc ajouté une fonction qui fait ça récursivement :

 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 : Ajout de la vérification is_object() dans la boucle du tableau pour éviter une exception get_class() dans le prochain appel extract_props() lorsque les éléments du tableau ne sont pas des objets, comme des chaînes ou des nombres.

14voto

Oleg Points 327

De toute façon. Vous devez créer une méthode publique dans votre classe pour renvoyer tous leurs champs encodés en json

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

3voto

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

    return json_encode($objectArray);
}

Personnellement, je pense que c'est une façon de procéder. Il est similaire à celui de Petah, sauf qu'il s'aligne bien sur l'encapsulation, car le tableau est rempli à partir de l'objet.

Mettez cette fonction dans votre objet ou en tant que trait à utiliser par votre objet. A chacun son truc cependant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X