Convert object to json in php

4

I'm trying to create a class that saves objects of type Conta to a json file, however, when saving the file, the object information is not saved, just this:

  

[[], {}]

My class that is reading and saving in json is:

class JSONCustom {

    private $list = null;
    private $jsonFile = "teste.json";

    public function __construct() {
        if (file_exists($this->jsonFile)) {

            $string = file_get_contents($this->jsonFile);
            $json = json_decode($string, true);
            $this->list = $json;
        } else {
            $this->list = Array();
        }
    }

    public function getList() {

        return $this->list;
    }

    public function add($item) {
        //$jsonObject = get_object_vars($item);
        $this->list[] = $item;
        $this->save();
    }

    private function save() {
        if ($this->list != null) {
            $string = json_encode($this->list);
            file_put_contents($this->jsonFile, $string);
        }
    }
}

$agencia = new JSONCustom();

$conta = new Corrente(123, "teste", 3.10);
$agencia->add($conta);

var_dump($agencia->getList());

The Current class:

class Corrente extends Conta{
    private $tarifaManutencao = 12.5;

    public function __construct($num, $prop, $saldo){
        parent::__construct($num, $prop, $saldo);
    }

    public function getTipoconta(){
        return "Corrente";
    }

    public function listarDados(){
        return parent::listarDados().
        "\nTipo de Conta: ".$this->getTipoconta().
        /* "\nTarifa de Manutencao: ".$this->tarifaManutencao; */
        "\nTarifa de Manutencao: ".CalcularFloat::formatarMoeda($this->tarifaManutencao);
    }

    public function cobrarTarifa(){
        if($this->getSaldo() < $this->tarifaManutencao){
            $this->habilitarPermissoesEspeciais();
            $this->sacar($this->tarifaManutencao);
            $this->desabilitarPermissoesEspeciais();
        }else{
            $this->sacar($this->tarifaManutencao);
        }
    }

    protected function setTarifaManutencao($novaTarifa){
        $this->tarifaManutencao = $novaTarifa;
    }
}

And my abstract class Account:

abstract class Conta{
    private $numero;
    private $proprietario;
    private $saldo;
    private $permissoesEspeciaisHabilitadas = false;

    public function __construct($num, $prop,$saldo){
        if($num < 0){
            throw new ExcecaoNumeroInvalido("Numero da conta nao pode ser negativo.");
        }else if($saldo < 0){
            throw new ExcecaoValorNegativo("Saldo nao pode ser negativo.");
        }
        $this->numero = $num;
        $this->proprietario = $prop;
        $this->saldo = $saldo;
    }

    public function getNumero(){
        return $this->numero;
    }

    public function getProprietario(){
        return $this->proprietario;
    }

    public function getSaldo(){
        return $this->saldo;
    }

    public function listarDados(){
        return "Numero: ".$this->numero.
        "\nNome: ".$this->proprietario.
        /* "\nSaldo: ".$this->getSaldo(); */
        "\nSaldo: ".CalcularFloat::formatarMoeda($this->getSaldo());
    }

    protected function permissoesEspeciaisHabilitadas(){
        return $this->permissoesEspeciaisHabilitadas;
    }

    public function habilitarPermissoesEspeciais(){
        $this->permissoesEspeciaisHabilitadas = true;
    }

    public function desabilitarPermissoesEspeciais(){
        $this->permissoesEspeciaisHabilitadas = false;
    }

    protected function verificarCondicoesParaSaque($valor){
        if ($valor < 0){
            throw new ExcecaoValorNegativo("Valor de saque nao pode ser negativo.");
        }else if($valor > $this->saldo && !$this->permissoesEspeciaisHabilitadas()){
            throw new ExcecaoSaqueInvalido("Sem saldo suficiente para este valor saque.");
        }
    }

    public function sacar($valor){
        $this->verificarCondicoesParaSaque($valor);
        $this->saldo = CalcularFloat::subtrair($this->saldo, $valor);
    }

    public function depositar($valor){
        if($valor < 0){
            throw new ExcecaoValorNegativo("Valor de deposito nao pode ser negativo.");
        }
        $this->saldo = CalcularFloat::somar($this->saldo, $valor);
    }

    public abstract function getTipoconta();
}

When executing a var_dump($agencia->getList()); , the result returns the object normally:

array (size=3)
  0 => 
    array (size=0)
      empty
  1 => 
    array (size=0)
      empty
  2 => 
    object(Corrente)[2]
      private 'tarifaManutencao' => float 12.5
      private 'numero' (Conta) => int 123
      private 'proprietario' (Conta) => string 'teste' (length=5)
      private 'saldo' (Conta) => float 3.1
      private 'permissoesEspeciaisHabilitadas' (Conta) => boolean false

However when converting the array to json in $string = json_encode($this->list); the array is not converted and saves only the one mentioned at the beginning of the question.

    
asked by anonymous 10.11.2015 / 18:13

3 answers

8

I was able to get all the attributes of my Corrente class and those inherited from the Conta class, by adding the JsonSerialize in both classes, as per the SOen reference / a> quoted by @rray.

This interface forces you to implement the jsonSerialize() method that I added in the Conta class:

public function jsonSerialize() {
        return get_object_vars($this);
    }

And in class Corrente I did the same, however, by calling the jsonSerialize() of the parent class, and then joining the resulting arrays of the two classes, containing all the attributes of the two classes:

public function jsonSerialize() {
    $vars = array_merge(get_object_vars($this),parent::jsonSerialize());
    return $vars;
}

Now the object is being saved full, see the output of print_r :

[
  {
    "tarifaManutencao": 12.5,
    "numero": 123,
    "proprietario": "teste",
    "saldo": 3.1,
    "permissoesEspeciaisHabilitadas": false
  }
]

    
11.11.2015 / 12:24
3

Private members are not converted by json_encode() their class so in this case you can implement a method that gets all the 'variables' of the class and return a json.

Example that reproduces the error:

class Pessoa {
    private $id = 99;
    private $nome = 'teste';
    private $idade = 20;
}

echo json_encode(new Pessoa());

Example that works:

class Pessoa {
    private $id = 99;
    private $nome = 'teste';
    private $idade = 20;

    function serialize(){
        return json_encode(get_object_vars ($this));
    }   
}

$p = new Pessoa();
echo json_encode($p->serialize());

Reference

PHP json_encode class private members

    
10.11.2015 / 18:28
2

I've been through this problem and found this solution:

    if ($_GET['tipo'] == 'GET_OBJECT'){ 
        header("Content-type: application/json; charset=utf-8");
        $object = $_GET['object'];
        $objectController = new ObjectController();
        $objects = $objectController->getObjects($param);
        $lista_json = array("objects_array" => array());

        foreach($objects as $object){
            $obj = array (
                "attribute1" => $object->getAttribute()
            );

            array_push($lista_json["objects_array"], $obj);
        }
        echo json_encode($lista_json);
    }

I hope that's the solution to your problem too, even though the code is completely different. I even check before the first IF what the method is, whether it was a GET, PUT, DELETE, POST, but that part is not so important to your problem.

if ($_SERVER['REQUEST_METHOD'] == 'GET') {

    // Continuação do código, incluindo o código mencionado acima

}
    
10.11.2015 / 18:25