Postcards From My Life

Lint I find in my mind’s belly-button.
  • Home
  • Consulting
  • Resume
  • Subscribe
  • epk
« Another Valentines Day Poem
Sixty Second Tech, the Tech Podcast for Non-Tech People. »

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

Dear Reader,

Ok, this one is just stupidity on my part but I’m going to post this here so that hopefully others can learn from my mistake.

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 __construct()
    {
        $this->_data = array('wifesBirthDay' => '',
                             'nuclearLaunchCode' => '');

    } 

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

    public function __set($index, $value)
    {
        if (isset($this->_data[$index])) {
            $this->_data[$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. 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.

Obviously my brain simply chose to ignore this detail.

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.)

Until next time,
(l)(k)(bunny)

=C=

[Post to Twitter] 

Related posts

  • php|architect’s Guide to Programming the Zend Framework (8)
  • Book is Available, Support Site is Live (3)
  • 5 Tools Every PHP Developer Should Master (19)

Tags: FireBug, JSON, PHP, zend framework

This entry was posted on Thursday, February 21st, 2008 at 9:30 pm and is filed under JavaScript, PHP, Programming, zend framework. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

9 Responses to “I called Zend_Json::encode(), so WTH are all my properties?”

  1. fangel Says:
    February 22nd, 2008 at 2:14 am

    A theory: Implementing a SPL Iterator for your object will fix the issue.

    I don’t know how Zend_Json::encode works, but if it does a foreach($obj ..) then adding a simple SPI Iterator interface to your object will make it work correctly.. If it uses reflections I’m not sure what will happen..
    Worth a shot imho..

    XOXO

  2. Cal Evans Says:
    February 22nd, 2008 at 7:32 am

    Hi fangel!

    Thanks for leaving a comment.

    IIRC, and I’ll be honest in saying I’ve not looked at the code in a while, Zend_Json uses the naive json_encode method if it’s available. In my case it was. So while my post was specifically about Zend_Json, it applies as well to json_encode().

    Also, honestly, I wouldn’t want it to operate any other way. In hindsight, this is the proper way for it to work. I mark properties protected for a reason and it’s real easy to expose them if I need to.

    That having been said, yes, if I’m implementing JSON encoding nativly in PHP, it would be possible to do it your way and be able to get a more complete representation of the object.

    Thanks again for taking the time to lave a comment.

    =C=

  3. PHPDeveloper.org Says:
    February 22nd, 2008 at 11:18 am

    Cal Evans’ Blog: I called Zend_Json::encode(), so WTH are all my properties?…

    In dealing with a little JSON encoding and objects in a ……

  4. deminy Says:
    February 22nd, 2008 at 2:37 pm

    Well… Inside the magic function __set() you defined, I think
    if (isset($this->_data[$index])) {
    should be
    if (!isset($this->_data[$index])) {

  5. Cal Evans Says:
    February 22nd, 2008 at 3:00 pm

    Hi Deminy,

    Thanks for posting!

    Actually no, it’s that way on purpose but that code was scraped from my real class to build the example. In the real code, I build the array with all the elements blank in the __construct. This way, I can’t accidentally add new properties to the object that would cause me problems later. I’ll correct the example. Thanks for pointing that out.

    =C=

  6. fangel Says:
    February 24th, 2008 at 4:34 am

    I did some tests and, if using json_encode, having a Iterator for the object doesn’t help out.
    So no, that wouldn’t help on you problem..

    I, personally, think I would prefer it to actually work. If you expose a iterator for you object, I would expect any code that needs access to the members of this class to use the iterator. Instead it uses some “magic” code that finds the public members.
    Exposing a Iterator, in my mind, means “if you need to loop though the variables in this class – use this Iterator”. But json_encode() doesn’t do this..

    -f

  7. Cal Evans Says:
    February 24th, 2008 at 8:56 am

    reHi fangel!

    First, I think I may have explained it poorly. Having an iterator does not solve the problem. However, since ALL we are transferring to the front-end is properties, having a method that I can quickly pull out the array of properties and json encode THAT does solve the problem.

    Second, json_encode does work the way most of us would expect it to. It iterates through the public properties and encodes them. The mistake I made was to make my array of properties protected…actually, it wasn’t a mistake, it was the right thing to do for the way I was coding.

    There is no magic to getProperties() and I would never expect json_encode or Zend_Json::encode() to recognize that method and use it. I was a solution for the problem I had.

    Thanks for writing.

    =C=

  8. PrettyCoder Says:
    February 25th, 2008 at 3:00 am

    public function getProperties($skip = array())
    {
    return array_diff_key($this->_data, array_flip($skip));
    }

    Sorry, couldn’t resist.

  9. Cal Evans Says:
    February 25th, 2008 at 7:11 pm

    ZOMG!

    Hey, never apologize for doing a better job. I knew array_flip() existed but don’t think I’ve ever used it and I didn’t even know array_diff_key() was there.

    Thanks, I’ve updated my code.

    =C=

  • php|tek 09



    Zend Framework and the CLI

    A Manager's Guide to
    Telecommuting

  • My New Project

  • Sponsors and Ads

  • About Me

    cal_evansThis is my blog. Sometimes it's my deep thoughts, sometimes it's a journal of things I've learned. Every now and then it's my box of shattered dreams. Most of the time though, it's just the place I like to write. Sit with me as I show you some postcards from my life. While you are here, do me a favor and leave a comment.

    If you are looking for my contact information, bio, picture, ASL, check out my EPK.

    My name is Cal Evans and this is my blog.



    Follow me on FriendFeed!

    View Cal Evans's profile on LinkedIn

  • My First Book

  • Tags

    Apache API Apple article C.C. Chapman Cal Evans CIO Magazine Consulting customer service developers devzone dr. dobbs elizabeth naramore facebook FireBug flock fun hiring IBuildings iPod Kathy Evans linkedin love Marketing nerd herding PHP php abstract phparchitect php developers podcast poem respect securephphosting sixty second tech southwest airlines spaz terry chay tivo twitter upgrade valentine video wordpress zend zend framework

  • RSS The Lovely and Talented Kathy’s blog

    • Fushi Copperweld Website
    • Cal Evans’ Blog
    • KathyEvans.biz V2.0

  • RSS Sixty Second Tech

    • UTC
    • FireFox 3
    • The New Mediology on Twitter
    • MobileMe
    • Amazon’s S3
    • Attention, Not SERP!
    • I Want Sandy
    • Pipes!
    • Get Your Head in the Cloud!
    • Rich Internet Applications

  • Categories

    • Apache
    • Apple
    • BlogBling
    • Blogging
    • Consulting
    • Entertainment
    • Entrepreneurship
    • Exim
    • flex
    • hosting
    • Humor
    • JavaScript
    • jobs
    • Long Form
    • Mac
    • Management
    • Marketing
    • Me
    • photography
    • PHP
    • podcasting
    • Programming
    • Quickies
    • RSS
    • Silly-Con Valley
    • SQL
    • Technology
    • twitter
    • Web 2.0
    • wordpress
    • WordPress Plugins
    • writing
    • zend framework

  • RSS PHP Podcasts

    • The ZendCon Sessions Episode 21: PDO: PHP Data Objects
    • The ZendCon Sessions Episode 20: Distribution and Publication With Atom Web Services
    • The ZendCon Sessions Episode 19: Static and Dynamic Analysis at Ning
    • PHP Abstract Podcast Episode 41: Zend Framework 1.8
    • The ZendCon Sessions Episode 18: Of Haystacks and Needles
    • Zend_Db Update and Delete
    • The ZendCon Sessions Episode 17: SQL Query Tuning: The Legend of Drunken Query Master
    • Zend_Db Insert and Read
    • The ZendCon Sessions Episode 16: PECL Picks - Extensions to make your life better
    • Integrating Bits on the Run into Zend

  • Vanity Chart

    English posts that contain "Cal Evans" per day for the last 30 days.
    Technorati Chart
    Get your own chart!

  •  

    February 2008
    M T W T F S S
    « Jan   Mar »
     123
    45678910
    11121314151617
    18192021222324
    2526272829  

  • XBox Gamer Card

  • Blogs of friends

    • Ashley Evans
    • Cory
    • Davey Shafik’s Pixelated Dreams
    • Daytona Twentyfour
    • Fred Leo’s Blog
    • Louis Davidson
    • The Lovely and Talented Kathy

  • Me

    • Best. Webhosting. Ever.
    • Cal Evans Dot Com
    • Cyrano’s Apprentice
    • Evans Internet Construction Company
    • My Life as a Child
    • PHP Podcasts
    • Sixty Second Tech

  • Archives

    • June 2009
    • May 2009
    • April 2009
    • March 2009
    • February 2009
    • January 2009
    • December 2008
    • November 2008
    • October 2008
    • September 2008
    • June 2008
    • May 2008
    • April 2008
    • March 2008
    • February 2008
    • January 2008
    • December 2007
    • November 2007
    • October 2007
    • September 2007
    • August 2007
    • July 2007
    • June 2007
    • May 2007
    • April 2007
    • March 2007
    • February 2007
    • January 2007
    • December 2006
    • November 2006
    • October 2006
    • September 2006
    • August 2006
    • July 2006
    • June 2006
    • April 2006
    • March 2006
    • February 2006
    • January 2006
    • December 2005
    • November 2005
    • October 2005
    • September 2005
    • August 2005
    • July 2005
    • June 2005

  • Flickr Recent Photos

    The Bike vs. The HillDSCN2058.JPGCute Dutch GraffitiIvo "Joe Cool" JanschDSCN2030.JPGDSCN2029.JPGDSCN2028.JPGDSCN2027.JPGDSCN2026.JPGDSCN2025.JPG

  • Meta

    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org


Postcards From My Life is proudly powered by WordPress
Entries (RSS) and Comments (RSS).