Shawn Stratton PHP Geek

16May/11Off

Accesors and Religion

Today I'm going to become flame bait, I'm going to talk about something that's highly controversial, not because most view points on it are wrong but because everyones differ and they're all wrong besides mine.  Well there went my attempt at being sarcastic, but seriously, this is one of those discussions that will always be highly controversial.

The Problem

Objects have properties which sometimes need special logic on how they are retrieved and set.  There are several solutions to this and everybody has a different view point about which is correct, none are pretty and all have drawbacks which range from writing extra code, creating something that has poor extensibility, or has issues with consistency.  These don't even breach the issues with IDE code completion and analysis.  Lets look at some of these solutions.

The Solutions

Direct Access to properties

So when you first start getting into objects the very first thing that most people do is create a whole bunch of public properties that are accessed like this

class stuff{
  1.   public $whatever;
  2. }
  3. $obj->whatever = 'whatever';

This works well, you can set things outside of the object and then have the object act on it, the problem comes in when you need to modify the way the data is handled when it's set or retrieved without hanging client code.  That's generally when people start writing accessor methods and changing client code which leads to our second solution.

Mixture of Accessors and Direct Property Accessors

Once you start seeing needs of modifying data as it's being assigned you'll start seeing code like this:

class whatever2{
  1.   public $whatever;
  2.   public $stuff;
  3.   public function setWhatever($value);
  4.   public function getWhatever();
  5. }
  6. $obj->stuff = 'stuff';
  7. $obj->setWhatever('whatever');

Usually this only lasts a little while, usually someone will completely forget about the accesor methods and work with the property directly and cause some great inconsistencies, then as an act of paranoia someone will mark the property as protected or private.  This is still a problem as it leads to great inconsistencies, then the next step comes up.

Accessors for everything

This is usually the level most hit and stay at, they start writing accessors for every property that's supposed to be publicly accessible, your code here will start to look like this:

class whatever{
  1.   protected $stuff;
  2.   protected $whatever;
  3.   public function getStuff();
  4.   public function setStuff($value);
  5.   public function getWhatever();
  6.   public function setWhatever($value);
  7. } 
  8. $obj->setStuff('stuff');
  9. $obj->setWhatever('whatever');

At this level consistency is no longer a problem and you can easily extend the functionality of your getters/setters which is awesome, some even figure out to return $this in the setters so they can do chaining, at which point you client code can look like this

  1. $obj->setStuff('stuff')->setWhatever('whatever'):

There are downsides with this though, you'll have to write two methods that have to be compiled and referenced for every property you have, this makes the code very verbose and very long.  Some people have solved this issue with __call which is called every time you call a function that doesn't exist.  This usually looks like:

class whatever{
  1.   protected $stuff;
  2.   protected $whatever;
  3.   public function __call($name, $params)
  4. }

With some logic you can easily have the function  check for get/set at the beginning of the method name; it works but it's slow and it means that IDE's won't detect the setters/getters  and magic is generally not the best thing.  The even worse case of this is people use __get and __set to overwrite everything, but it does work on every protected/public property and it's an easy way to centralize getters and setters.  This leads us to our last idea, which I personally think is the best way to handle the situation.

My Solution

Obviously we want the ability to overwrite the way things are set, we also need consistency so that we're backwards compatible and the developers don't get confused by what's set via setter and what's set via direct property access, ultimately we don't want to write a bunch of functions just to set and get the values of our properties, it's kinda silly actually, thinking of all those function calls and completely discarding PHP's Property Setting also seems a little foolish.  Anyway, ultimately I came up with the following solution and it works really well for me and the people I work with.

public function __set ($key, $value)
  1. {
  2.   //check if a accessor function exists
  3.   $accessor = 'set'.ucfirst($key);
  4.   if (method_exists($this, $accessor))
  5.   {
  6.     return $this->$accessor($value);
  7.   }
  8. }
  9. public function __get ($key)
  10. {
  11.   $accessor = 'get'.ucfirst($key);
  12.   if (method_exists($this, $accessor))
  13.   {
  14.     return $this->$accessor();
  15.   }
  16. }

With this code in our Model Abstract we are able to call everything via the default method of setting properties i.e.

  1. $object->property = $value;

Most properties would then be marked public, with properties meant to be accessed in this way being set to protected and having set/get functions written for them (that are then marked protected to keep the api clean and to keep interaction sane.)  There is one obvious glaring downside to this though, this does not work with IDE auto-completion, and boy do I wish it did, but out of all things to sacrificed that's pretty minimal.  Also I should mention that the above code does not do any error setting which has been omitted in my example.

Conclusion

There are many ways you can skin this metaphorical cat, however, they each have trade-offs.  Ultimately I went with the methodology that made the most sense to me and that passed our architectural standards (consistency) but you may have a different use case and that's fine.

Filed under: PHP 9 Comments
5May/11Off

PHP Community Conference

Week before last I had the pleasure of attending the PHP Community Conference in Nashville (my old stomping grounds,) I saw several friends  I hadn't seen in a while and had a blast but I also learned a lot.  First to any of you who are going home a little ill, if it's my fault I'm very sorry, it seems that on the first day of the conference I started falling ill and I still think that now I have a sinus infection due to the building that the conference was held in but that's another matter. Now on to the good, I wanted to share some things I walked away with:

Telling Stories is teaching, but maybe more effective

The entire conference was based around the premise that instead of leading tutorials the speakers tell of their experience in a story like format.  This worked really well, the content wasn't dry and repetitive and because of that it was easier to digest.  It was also really interesting to hear about some of the things that at traditional conferences would only have been discussed in the hallway track (Such as what the hell happened to PHP 6 and unicode support).

Everyone has a story to tell

The more I listened to the speakers the more I wanted to hear other people talk about their own stories (sorry speakers but I've heard many of you before or read your blogs.)  I managed to get some time with other people that weren't necessarily well known community members and certainly not speakers at this conference, the stories I heard from these people probably taught me as much, if not more, than the conference taught me.  An interesting example was talking to several students from TN that were learning base Web Programming as a way of migrating their careers.

The changes in v2's of the various frameworks are major jumps

Matthew presented on ZF2 design patterns, Joël presented on Lithium, and Ryan Weaver ( a good friend of mine ) of course pimped Symfony 2 (unofficially) but each of these frameworks ( Lithium is based on Cake but is a major departure ) has taken leaps and bounds from their original release.  What's even more interesting, besides syntax, licensing, and some external bundled library components, each of these libraries is starting to go almost the exact same way (maybe not Lithium as much because they are trying to get ahead of the curve).

Developers do not know how to ride mechanical bulls

To all of those who tried, you had a valiant attempt, but as a rule yeah.

The direction of the web is towards open content

There was one product that was shown off (a little bit anyway) at the conference which really happened to highlight an idea of what I've been thinking about a lot lately, content that is based around a user rather than a content provider.  The application in question is Gimme Bar and I had a chance to sit down with Sean Coates to talk about it a bit, in talking with Sean I was introduced to standards like oEmbed (which is something I'm now working on @ work.)  If you are interested in this topic, please check out  http://www.alistapart.com/articles/orbital-content/ which is Cameron's Article on the idea behind Gimme Bar, also if you're interested in oEmbed I'm planning on writing a blog entry once I've built our implementation.

PHP has blown up everywhere

The job market for PHP is dry on developers everywhere, I found out about companies looking for developers throughout the company @ the conference.  This is probably the best time in the lifetime of PHP to be a PHP Developer.  Due to the migration to PHP from Java, for cost benefits and other reasons, as a PHP based developer we now seem to have our choice of where we want to work and provided it's not some crazy place (Flickr, Yahoo!, etc) there's not a crazy fight to get your foot in the door.

That Chayisms are awesome

I didn't really learn this here but until I actually got to hear Terry Chay read out Chayisms it didn't really hit home how awesome they really are.  As an example here are some Chayisms:

  • Terry Chay doesn't get stage fright. Stages get frightened of Terry Chay.
  • Terry Chay doesn't bother hashing his password; his password is so perfect that the mere sight of it would kill you
  • One ounce of Terry Chay contains seven pounds of awesome

And one I came up with :

  • EC2 didn't come down, Terry Chay just needed it to process his photos.

Ehh that kind of sucked but if you come up with one please submit it and I'll see if I can get them added to http://www.phpdoc.info/chayism/

Justifying Conference Costs

So the big thing I hope to share with you is the idea that Conferences are a great value, even with the high prices we see on some conferences (ZendCon, PHP|Tek, etc) but these costs are easily justifiable.  As an example of what I've used to justify my costs upon returning from the conference, one change that I talked with Matthew Weier O'Phinney showed us an 18% performance increase across one of our work projects.  18% doesn't sound like much, specifically in our case it's only about 25ms, but we're already highly optimized (if you do the math our entire request is about 117ms and we saw runs as low as 91ms after this change, but that's 18% across many servers and the entire change only took me an hour.

Would I recommend PHP Community Conference

You better believe it, what you can learn from the people attending is almost as great as those that are presenting.  Also the ticket was dirt cheap and Nashville is a fun city to visit, it's my impression that this will become a yearly conference and I honestly believe that you should make plans now to attend next year.  I split my hotel and travel to Nashville with a fellow Atlanta PHP User Group member so I managed to get out of the entire experience at roughly around 600 bucks.  If you want to go next year or you went this year please ping Ben Ramsey (@ramsey), Lisa Denlinger (@lisamusing) and Nick Sloan (@nickasloan) and let them know, I'm 100% sure that they enjoy feedback!

Filed under: PHP No Comments