jul
2008
PHP __set and __get Magic methods
Object oriented programming principles encourage encapsulation, i.e. containing all the functionality inside a class. Usually this means member variables should be private or protected, one of the common ways to do this is with various set and get methods. In the case of a user class it may have setName, getName, setAge, getAge and so on. This can be time consuming to set up, change and maintain. The magic methods set and get provide a quick way to implement generic set and get methods.
<?php class Foo{ private $name; private $age; public function setName($name){ $this->name = $name; } public function getName(){ return $this->name; } public function setAge($age){ $this->age = $age; } public function getAge(){ return $this->age; } } $foo = new Foo(); $foo->setName("Dougal"); $foo->setAge(10); echo $foo->getName(). " is " . $foo->getAge(). " years old\n"; class Bar{ private $name; private $age; public function __set($var, $val){ $this->$var = $val; } public function __get($var){ return $this->$var; } } $bar = new Bar(); $bar->name = "Dougal"; $bar->age = 10; echo $bar->name . " is " . $bar->age. " years old";
The script outputs the same thing twice, just showing different methods; "Dougal is 10 years old Dougal is 10 years old"
In the above example class Foo uses set and get methods while class Bar uses the magic methods. To summarise set and get, basically if you are trying to access a property of an object (and it has a get method) the name of the property you are requesting is passed into the get method and it can handle it how it wants. set works the same but it is only called when you attempt to assign a value to a member variable. The only difference being set takes two paramemters, the variable its setting and the value. You might wonder what the point in set and __get is, well one good example is when a class has dynamic properties.
<?php class DynamicFoo{ private $vars = array(); public function __construct(){ } public function __set($var, $val){ $this->vars[$var] = $val; } public function __get($var){ if(isset($this->vars[$var])){ return $this->vars[$var]; } else { throw new Exception("Property ‘$var’ does not exist"); } } } $dynamicFoo = new DynamicFoo(); $dynamicFoo->hello = “world”; // sets the properly echo $dynamicFoo->hello; // displays “world” echo $dynamicFoo->bar; // throws an exception ?>
You can now also do some slightly more interesting things too... take this example...
<?php class DynamicUser{ private $firstname = ""; private $surname = ""; public function __set($var, $val){ $this->$var = $val; } public function __get($var){ if(isset($this->$var)){ return $this-$var; } elseif(method_exists($this, $var)){ return $this->$var(); } else { throw new Exception("Property ‘$var’ does not exist"); } } public function fullname(){ return $this->firstname . " " . $this->surname; } } $x = new DynamicUser(); $x->firstname = "dougal"; $x->surname = "matthews"; echo $x->fullname;
I wouldn't really recommend this way, its more an example of what can be done rather than anything else. Basically the above method "guesses" that if the property doesn't exist you meant to call a method by the same name and returns the result of that method instead.
The nice thing about this is it can be completely transparent to the user.
Next I'll be looking at a __call, a magic method for when you call functions!
Short url - Related tags: get, magic-methods, php, set