Martin Sheppard
Martin Sheppard

Reputation: 5

json_encode result inside json_encode

I need your help, i don't get it on my own. May the gap with me.

I got two classes: The first one (Application) has a method (toJson) to return its private variables as json-string.

The second (Problem) contains the first class and is able to return its own content and the content of its child as json.

Now, if i call the toJson-method of the superior second class, this method calls the toJson-method of its child.

Both toJson-methods are using json_encode. The logical consequence is, that the final-result contains escape characters.

{"Application":"{\"Abbreviation\":\"GB\",\"Identifier\":1,\"Name\":\"Great Bounce"\"}"}

The toJson-Method of Application is similar to this:

public function toJson()
{
    return json_encode(array(
        "Abbreviation" => $this->_Abbreviation,
        "Identifier" => $this->_Identifier->getId(),
        "Name" => $this->_Name
    ));
}

The toJson-Method of Problem:

public function toJson()
{
    return json_encode(array(
        "Application" => $this->_Application->toJson();
    ));
}

The escape chars are causing issues with JavaScript. Does someone comes a solution or different implementation into mind?

Upvotes: 0

Views: 1085

Answers (4)

Andrii Mishchenko
Andrii Mishchenko

Reputation: 2694

To make it more flexible I would separate toJson methods on toArray and toJson:

Application class:

public function toArray() {
    return array(
        "Abbreviation" => $this->_Abbreviation,
        "Identifier" => $this->_Identifier->getId(),
        "Name" => $this->_Name
    );
}

public function toJson() {
    return json_encode($this->toArray());
}

Problem class:

public function toArray() {
    return array(
        "Application" => $this->_Application->toArray();
    );
}

public function toJson() {
    return json_encode($this->toArray());
}

By the way, it would be good to wrap all this into interfaces.

Upvotes: 2

deceze
deceze

Reputation: 522075

What the inner class is really returning is a string, not an array representation of itself. So the outer class is encoding a string; that this string contains JSON data is pretty much irrelevant. I'd suggest the inner class should have a method to return itself as an array representation in addition to a JSON representation:

public function toJson() {
    return json_encode($this->toArray());
}

public function toArray() {
    return array(
        "Abbreviation" => $this->_Abbreviation,
        "Identifier" => $this->_Identifier->getId(),
        "Name" => $this->_Name
    )
}

The outer class then takes this array representation:

public function toJson() {
    return json_encode(array(
        "Application" => $this->_Application->toArray();
    ));
}

Upvotes: 3

markdwhite
markdwhite

Reputation: 2449

This would still allow you to access the methods independently:

Application:

public function toJson()
{
    return json_encode($this->toArray());
}

public function toArray()
{
    return array(
        "Abbreviation" => $this->_Abbreviation,
        "Identifier" => $this->_Identifier->getId(),
        "Name" => $this->_Name
    );
}

Problem:

public function toJson()
{
    return json_encode(array(
        "Application" => $this->_Application->toArray();
    ));
}

Upvotes: 2

Paul
Paul

Reputation: 141829

You could decode the data, to get an object, which will be encoded again by json_encode:

public function toJson()
{
    return json_encode(array(
        "Application" => json_decode($this->_Application->toJson());
    ));
}

This way, you get only the properties of _Application that are encoded by its toJSON method.

Upvotes: 0

Related Questions