Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I json encode private properties in php?

Tags:

json

php

I am working with doctrine 2 and zend framework 1.11. Public properties are discouraged in Doctrine 2, so I made my entity properties private. However I have just learned that Zend_Json::encode() and json_encode() will not see private / protected properties and thus, not add them in the their output.

Therefore when I use either, and var_dump, I get an empty set eg string(4) "[{}]".

It turns out I have to write my own function to do the encoding. I was hoping someone has a solution that I can use instead.

like image 876
Napoleon Avatar asked Jul 07 '11 16:07

Napoleon


2 Answers

The entire point of having member variables as private is to prevent them from being visible to any external code (serialize is an exception because the entire object will need to be restored between sessions).

Instead of json_encoding this object, you should perhaps create an interface "encodeable" with a method "encode." This will return a json-encoded string of any of the members required by this object. This gives you additional control because instead of serializing all members, you can choose the ones you want to serialize and even perform operations on them to serialize other data.

Actually you can imlement the JsonSerializable interface which works directly with json_encode.

class MyClass implements \JsonSerializable
{
    public function jsonSerialize()
    {
        return get_object_vars($this);
    }
}

$myObject = new MyClass();
echo json_encode($myObject);
like image 88
Explosion Pills Avatar answered Oct 03 '22 17:10

Explosion Pills


I believe php 5.4 has JsonSerializable which should make things easier but I'm using php 5.3.8. I've not tested this as much as I should and think I'm going to settle for having my properties public but this appears to work for my own classes:

class JSONEncoder{

public function json_encode($object){
    return json_encode($this->getFields($object));
}

private function getFields($classObj){
    $fields = array();
    $reflect = new ReflectionClass($classObj);
    $props   = $reflect->getProperties();
    foreach($props as $property){
        $property->setAccessible(true);
        $obj = $property->getValue($classObj);
        $name = $property->getName();
        $this->doProperty($fields, $name, $obj);
    }

    return $fields;

 }

 private function doProperty(&$fields, $name, $obj){

     if (is_object($obj)){
         $fields[$name] = $this->getFields($obj);
         return;
     }

     if (is_Array($obj)){
         $arrayFields = Array();
         foreach ($obj as $item){
             $key = key($obj);
             $this->doProperty($arrayFields, $key, $item);
             next($obj);
         }
         $fields[$name] = $arrayFields;
     }
     else 
         $fields[$name] = $obj;
 }
}
like image 41
Jon Avatar answered Oct 03 '22 18:10

Jon