Over a million developers have joined DZone.

I called Zend_Json::encode(), so WTH are all my properties?

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

The problem is simple, JSON encode a PHP object and send it back to the front end. Sounds simple and the last 100 times I wrote this code it was simple. This time, I was too smart for my own good. Here's the scenario. The object I'm encoding uses PHPs magic functions __get() and __set. __get() and __set() operate on a protected array named (drum roll please) $_data. (Stop me if you've heard this one)

class MyClass 
{
protected $_data;

public function __get($index)
{
if (isset($this->_data[$index])) {
return $this->_data[$index];
}
return null;
} // public function __get($index)

public function __set($index, $value)
{
if (isset($this->_data[$index])) {
$this->_data[$index] = $value;
return true;
}
return false;
} // public function __set($index, $value)

}

So I instantiate an instance of MyClass and set a few very important properties:

$myObject = new MyClass();

$myObject->wifesBirthday = '5/14';
$myObject->nuclearLaunceCode = 'dontPushThisButton';

Now, var_dump($myObject) returns what you think it would, you can see the protected array and the values.

It was at this point that while I was still able to type coherent code, my brain had checked out for the night because even though the manual for Zend_Json::encode clearly states:

When encoding PHP objects as JSON, all public properties of that object will be encoded in a JSON object.

(See the problem here?)

In my mind, the properties existed...right? Cause I could set them; however, since I'm laying it out here for you, it's easy to see that since $_data is a protected property, it wasn't getting passed.

Using FireBug (is there a better FireFox extension? I don't think so) I could see that my PHP was handing back an empty JSON string to be re-constituted on the client side.

The solution, once I realized what was happening, was quite simple. just create an array of the properties you want to pass back.

$payload = array('wifesBirthday'=>$myObject->wifesBirthDay, 'nuclearLaunchCode'=>$myObject->nuclearLaunchCode);
$output = Zend_Json::encode($payload);

That was my first cut and low and behold it works. However, a better solution came to mind.

class MyClass 
{
protected $_data;

public function __get($index)
{
if (isset($this->_data[$index])) {
return $this->_data[$index];
}
return null;
} // public function __get($index)

public function __set($index, $value)
{
if (isset($this->_data[$index])) {
$this->_data[$index] = $value;
return true;
}
return false;
} // public function __set($index, $value)

public function getProperties($skip=array())
{
$returnValue = array();
foreach($this->_data as $key=>$value) {
if (!in_array($key,$skip)) {
$returnValue[$key]=$value;
}
}

return $returnValue;
}
}

There, now I can simply write:

$payload = $myObject->getProperties();
$output = Zend_Json::encode($payload);

If I didn't want to disseminate the nuclear launch codes (I know I'm gonna start getting some weird searches now) I can write:

$payload = $myObject->getProperties(array('nuclearlaunchCode'));
$output = Zend_Json::encode($payload);

So I hope that by embarrassing myself publicly I can help at least one person. (For the record, it really only took me about 2 minutes to trace down the issue.)

=C=

 

Originally published on Postcards From My Life. Used by permission. 

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}