Show private and protected PHP members with json_encode

The Problem

This may be news to some, but json_encode() respects property visibility.

Meaning that if you have a class that looks like this...

class Thing {

    public $something;
    protected $protected_something;
    private $private_something;

    public __construct($pub, $prot, $priv) {
        $this->something = $pub;
        $this->protected_something = $prot;
        $this->private_something = $priv;
    }

    public get_private() {
        return $this->private_something;
    }

    public get_proctected() {
        return $this->protected_something;
    }
}

And you run one of these guys through json_encode()

$thing = new Thing("One", "Two", "Three");
echo json_encode($thing);

You'll end up with the following

{
    "something": "One"
}

json_encode() only serializes the publicly visible properties of an object. If you follow the getter/setter pattern (which I don't particularly recommend), this can be a neusense.

PHP < 5.4.0

The solution to this problem for those running PHP 5.3 or less (most of us), is to implement a json encoding function within your class. Which gives all your properties the visibility they need, and allows you to control the exact json representation of your object.

Using the example class above...

class Thing {

    ...
    public function to_json() {
        return json_encode(array(
            'something' => $this->something,
            'protected' => $this->get_protected(),
            'private' => $this->get_private()
        ));
    }
    ...
}

Now, you'll generate the json representation with your method (which uses json_encode() internally)...

$thing = new Thing("One", "Two", "Three");
echo $thing->to_json();

You'll end up with the following

{
    "something": "One",
    "protected": "Two",
    "private": "Three"
}

PHP >= 5.4.0

For all you lucky ones out there working in a PHP 5.4 environment, your solution is a bit more elegant

Simply implement the JsonSerializable interface and add the jsonSerialize function which should return the data structure you want to be represented in JSON.

Using the example class above...

class Thing implements JsonSerializable {

    ...
    public function jsonSerialize() {
        return [
            'something' => $this-&gt;something,
            'protected' => $this-&gt;get_protected(),
            'private' => $this-&gt;get_private()
        ];
    }
    ...
}

Now, when you run one of these guys through json_encode()

$thing = new Thing("One", "Two", "Three");
echo json_encode($thing);

You'll end up with the following

{
    "something": "One",
    "protected": "Two",
    "private": "Three"
}

This is the preferable solution, because now you don't have to write documentation for the users of your library/code how to convert your object to JSON, they simply use the native PHP JSON API.

Bonus: I want to just encode EVERY property

Just loop over the object inside any of the json methods above...

...
    $json = array();
    foreach($this as $key => $value) {
        $json[$key] = $value;
    }
    return $json; // or json_encode($json)
...