Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

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

DZone's Guide to

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

· Web Dev Zone ·
Free Resource

Jumpstart your Angular applications with Indigo.Design, a unified platform for visual design, UX prototyping, code generation, and app development.

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. 

Take a look at an Indigo.Design sample application to learn more about how apps are created with design to code software.

Topics:

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}