0

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?

3
  • you're trying to json encode something that is already encoded in json Commented Mar 24, 2014 at 15:41
  • 1
    Decode your JSON, assemble an object, and encode the whole thing. That's the only proper way to do this. Well actually, fixing your application to not return JSON for everything and only JSON-encoding at the right layer would be the proper way. Commented Mar 24, 2014 at 15:41
  • What kind of issues? JSON.parse can handle these perfectly fine, and directly injecting the JSON into code should work just as fine. You just have to decode twice. Commented Mar 24, 2014 at 15:46

4 Answers 4

3

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();
    ));
}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 This avoids the redundant decoding and encoding from my answer.
2

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();
    ));
}

Comments

2

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.

1 Comment

Hey Andrey, thank you, too. The seperation of toArray and toJson is attractive! Of course I already have an interface to implement :) Thanks :)
0

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.

2 Comments

Hey Paulpro, now I know that I have to go into bed. Thank you! Because I'm really interested in performance, this is mayby not the best choice (because of the architecture of the classes). Do you have an idea of a better architecture?
@MartinSheppard You're welcome, but consider the other answers as well. This answer will work for you, but the other answers will also work, and they avoid decoding and encoding the data an extra time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.