magic __get and __set style?

For a long time I’ve held that __get and __set in PHP were not all that hot  – mostly because it’s solely error handling.  There’s no way to deal invoke __get or __set behaviour for properties that are defined on a class.  That’s sort of a beef for another post (I’d started an RFC some time ago on trying to extend that behaviour to defined properties as well as undefined, but didn’t finish it, life got in the way, and various other reasons – again, perhaps for another day).

For those who insist on using __get/__set, I *typically* see this sort of style code:

class foo
{
 protected $_holder = array();
  public function __set($name,$value) {
   if($name=='foo') {
    $this->_holder['foo'] = $value;
   }
   if($name=='bar') {
    $this->_holder['bar'] = $value;
   }
// etc
  }
}

The effect is to cram a bunch of unrelated code in to the __get/__set overloading methods.

Should I need to use __get/__set again, my new approach will be

<?php
class foo
{
 protected $__foo;
 protected $__bar;
 
  public function __set($name,$value) {
   if(method_exists($this,"set$name"))
   {
     $this->{"set$name"}($value);
   }
  }
  public function __get($name) {·
   if(method_exists($this,"get$name"))
   {
     return $this->{"get$name"}();
   }
  }
  protected function setFoo($value)
  {
    $this->__foo = $value;
  }
  protected function setBar($value)
  {
    $this->__bar = $value;
  }
  protected function getFoo()
  {
    return $this->__foo;
  }
  protected function getBar()
  {
    return $this->__bar;
  }
·
  }
$f = new foo();
$f->foo = "new";
echo $f->foo;

This feels cleaner – perhaps others of you already take this approach? It’s just not commonly reflected in PHP tutorial sites that I come across, and it’s been bugging me for a while. I also see “mysql_connect() or die()” in books published in 2010 though, which indicates the majority of stuff published on PHP is still behind the times.

What I’d like to see (and what my RFC would have been about) is PHP to look for the existing of internal getXXX and setXXX methods on property accesses all the time, and not just fall back to __get/__set on error conditions. Being able to call $foo->name, and having PHP call getName() *if the method exists* would make for easy to read code that’s also very extendable.

Perhaps I’ve written about this before – I can’t remember. Certainly, some of our PHP user group has heard me go on about this before. Now it’s there for the ages. :)

How do the rest of you deal with wanting to have overridable property access? Do you just have manual get/set() methods for every property access? Or some other approach?


I'm currently working on a book for web freelancers, covering everything you need to know to get started or just get better. Want to stay updated? Sign up for my mailing list to get updates when the book is ready to be released!

Web Developer Freelancing Handbook

Be Sociable, Share!

Leave a Reply