My name is  
Jurgens du Toit.
Systems Developer.
Problem Solver.

About Me

Technology and Solving Problems are my passion. I'm a South African that loves my wife, life, and coding.

I'm writing a book!

The Logstash Config Guide

Buy it now on Leanpub

24 February 2012

json-encode'ing Private and Protected Properties

By Jurgens du Toit

When you json_encode an object, it will ignore all protected and private properties if the json_encode isn’t called from within the object. Sometimes you want to output the protected and private properties of an object when you’re JSON encoding it. Here’s how to do it in an easy and elegant way:

##The Problem

The properties of an object json_encode includes in it’s eventual output depends on the scope of the function call: If it’s from inside the object, it will include all the properties, private and protected. If it’s from outside of the object, it will only include the public properties.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
class Tester
{
    public $public       = 'Public';
    protected $protected = 'Protected';
    private $private     = 'Private';
    function foo()
    {
        echo json_encode($this);
    }
}
$test = new Tester();
$test->foo(); //Outputs {"public":"Public","protected":"Protected","private":"Private"}
echo json_encode($test); //Outputs {"public":"Public"}

This isn’t necessarily the desired outcome. Sometimes you want more control over what is being included in the encoding function.

##The Solution

The easiest way to solve this is to add a _toJson function to your object, and call that instead of json_encode:

1
2
3
4
5
6
7
8
9
10
11
<?php
public function _toJson()
{
    $properties = $this->getProperties();
    $object     = new StdClass();
    $object->_class      = get_class($this);
    foreach ($properties as $name => $value) {
        $object->$name = $value;
    }
    return json_encode($object);
}

The getProperties function should return the properties you want to include in the encoding. At it’s simplest it can be

1
2
3
4
5
<?php
    public function getProperties()
    {
        return get_object_vars($this);
    }

Then, to call it, just check if the function exists, otherwise just call json_encode:

1
2
<?php
    echo method_exists($object, '_toJson') ? $object->_toJson() : json_encode($object);

It’s relatively simple to do it as a Decorator as well, which will enable you to give this functionality to multiple classes without the need to duplicate the code. See how I did it in the Backend-PHP framework.

Do you have a better way to do it? Say so in the comments.

blog comments powered by Disqus