On 16 November 2011 00:17, Rasmus Schultz <[email protected]> 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