Programming And More
Tags: programming   php5   oop   accessor methods  
Thu, 6/3/2010

Moin!
Yesterday I was telling you how to write better get and set methods. However, there is another way of doing it even better but I first thought it would limit you in your ability to write useful get and set methods but it’s not.

Just keep in mind that whenever you set a property php5 calls __get or __set and you can use them to make accessor methods like in ruby and I first thought this would limit you in the ability to create unique get and get methods but it’s not because php is able to verify if a named method is available inside the class or not.

That feature got me the following code:

class Car {
  private $mileage = 123000;

  function __get($f) {
    $m = "get_".$f;
    return method_exists($this,$m) ? $this->$m() : $this->$f;
  }

  function __set($f,$v) {
    $m = "set_".$f;
    return method_exists($this,$m) ? $this->$m($v) : $this->$f = $v;
  }
}

$mycar = new Car;
print $mycar->mileage; // 123000
$mycar->mileage = 124000;
print $mycar->mileage; // 124000



Executing this script will print out “123000124000” on your terminal which is perfectly fine though you might think you just set the private property “mileage” to some value but in fact the method __set did set the value for that private property “mileage”.

But now in the near future you decide that mileage can’t just be a simple number but needs some formatting attached to it (which would be bad practice here, but just to be clear), so you want to create your unique get-method, so you simply add it to your implementation:

class Car {
  private $mileage = 123000;

  function __get($f) {
    $m = "get_".$f;
    return method_exists($this,$m) ? $this->$m() : $this->$f;
  }

  function __set($f,$v) {
    $m = "set_".$f;
    return method_exists($this,$m) ? $this->$m($v) : $this->$f = $v;
  }

  function get_mileage() { 
    return $this->mileage." km\n";
  }
}

$mycar = new Car;
print $mycar->mileage; // 123000 km\n
$mycar->mileage = 124000;
print $mycar->mileage; // 124000 km\n



Executing this script will append ” km\n” to each “getted” value because “__get” tried to check if there is a “get_mileage” method available which evaluated to true so it simply called it.

Basically that’s it…you can do the same with “set” and just add your unique set-method:

class Car {
  private $mileage = 123000;

  function __get($f) {
    $m = "get_".$f;
    return method_exists($this,$m) ? $this->$m() : $this->$f;
  }

  function __set($f,$v) {
    $m = "set_".$f;
    return method_exists($this,$m) ? $this->$m($v) : $this->$f = $v;
  }

  function get_mileage() {
    return $this->mileage." km\n";
  }

  function set_mileage($newMileage) {
    if ($newMileage > 100000) {
      $this->mileage = 200000;
    } else {
      $this->mileage = $newMileage;
    }
  }
}

$mycar = new Car;
print $mycar->mileage; // 123000 km\n
$mycar->mileage = 124000;
print $mycar->mileage; // 200000 km\n



Now if you have a bunch of private properties you don’t need to write accessor methods for all of them. Just when you need them you’ll implement them and you will be fine :).

Andreas Schipplock.

Posted 11 months ago
Latest Tweets