Our PHP application makes use of json_encode($myObject) a lot, in conjunction with the mustache template library. It's awesome.
Trouble is, when returning json data from an ajax request it reveals the whole stucture of our objects, even if we don't have data assigned to them. A simple example:
Fetch a user via ajax and let the server return the object with json_encode($user)
The json:
"_userID":"1","_password":null,"_avatar":"0000723_8949d1d7eb0214fdf6c1af3cb6b66ed3_a.jpg","_blocked":null,"_confirmed":null,"_registerDate":null,"_lastVisitDate":null,"_template":null,"_referrerUserID":null,"_referrerURL":null,"_referrerDomain":null,"_referrerSearchTerms":null,"_confirmationHash":null,"_type":"Administrator"
and so on...
It reveals a lot about our objects when all I wanted to return was just a few fields.
Obviously I could rewrite our server side code to send back an array or different objects which are more limited but really that makes life harder and sort of prevents our clean template design which handles the same objects as our server does.
How do I clear all null properties from a json_encode. Does anybody else have this issue and a nice and clean solution?
Thanks to @gion_13, i've adapted his code and come up with a full solution:
$output = array('data'=>$data,'template'=>$template);
$output = object_unset_nulls($output);
echo json_encode($output);
function object_unset_nulls($obj)
{
$arrObj = is_object($obj) ? get_object_vars($obj) : $obj;
foreach($arrObj as $key => $val)
{
$val = (is_array($val) || is_object($val)) ? object_unset_nulls($val) : $val;
if (is_array($obj))
$obj[$key] = $val;
else
$obj->$key = $val;
if($val == null)
unset($obj->$key);
}
return $obj;
}
You should probably adapt your server side code to ignore the null values and return only the fields that are set (thus avoiding unnecessary bandwidth usage).
In your clientside code I suggest you have a set of defaults for your template and extend them received JSON with the defaults.
I'd you're using jquery, the code would look like this :
var defaults ={someDay:"somePlace"};
var object = $.extend({},defaults,theJson);
update
and in order to "clean up" the object in php, you can do something like :
foreach($obj as $k => $v)
if($v == null)
unset($obj[$k]);
From my experience when dealing with objects and JSON I do not think there is a way without iterating over each value. I always find it better to have a _toJson method implemented within the class, and in that do all the necessary preparations before encoding it to JSON (utf8-encoding issues, use getters instead of calling variables directly etc).