On 16 November 2011 00:17, Rasmus Schultz <ras...@mindplay.dk> wrote: > Here's a better example of something useful that actually works: > > trait Accessors > { > public function __get($name) > { > return $this->{'get'.$name}(); > } > > public function __set($name, $value) > { > $this->{'set'.$name}($value); > } > } > > class OrderLine > { > use Accessors; > > public $price; > public $amount; > > public function getTotal() > { > return $this->price * $this->amount; > } > } > > $line = new OrderLine; > > $line->price = 20; > $line->amount = 3; > > echo "Total cost: ".$line->total;
I like that example. It shows, at a fairly simple level, the ability to compose a class from potentially multiple traits. Putting the __magic_methods in a trait, what a great idea. This mechanism is allows for all sorts of easy to expand ideas. You _COULD_ use this trait to implement discrete getters and setters ... <?php /** * Trait to provide setter and getter functionality * with an exception for any missing method. */ trait Accessors { public function __get($name) { if (method_exists($this, 'get' . $name)) { return $this->{'get' . $name}(); } elseif (property_exists($this, $name)) { return $this->{$name}; } else { throw new Exception("Cannot retrieve value of '$name'."); } } public function __set($name, $value) { if (method_exists($this, 'set' . $name)) { $this->{'set' . $name}($value); } elseif (property_exists($this, $name)) { $this->{$name} = $value; } else { throw new Exception("Cannot set value for '$name'."); } } } /** * @property float $price * @property float $amount * @property float $tax * @property-readonly float $total */ class OrderLine { use Accessors; protected $price; protected $amount; protected $tax; public function getTotal() { return $this->price * $this->amount * (1 + ($this->tax / 100)); } protected function getPrice() { return $this->price; } protected function getAmount() { return $this->amount; } protected function setPrice($price) { $this->price = $price; } protected function setAmount($amount) { $this->amount = $amount; } } $line = new OrderLine; $line->price = 20; $line->amount = 3; $line->tax = 10; echo "Total cost: ".$line->total; ?> outputs ... Total cost : 66 So, the actual methods are hidden from public, but a developer can extend the class to add additional processing. Interestingly, I've used property_exists to expose public access to protected properties. I suppose that is always possible. Bad design really. I would guess you wouldn't mix the different access mechanisms (public/protected/private, __get/__set, getter()/setter()). Richard. -- Richard Quadling Twitter : EE : Zend : PHPDoc : Fantasy Shopper @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY : bit.ly/lFnVea : fan.sh/6/370 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php