Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:56339 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 99929 invoked from network); 16 Nov 2011 09:11:28 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 16 Nov 2011 09:11:28 -0000 Authentication-Results: pb1.pair.com smtp.mail=rquadling@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rquadling@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.161.42 as permitted sender) X-PHP-List-Original-Sender: rquadling@gmail.com X-Host-Fingerprint: 209.85.161.42 mail-fx0-f42.google.com Received: from [209.85.161.42] ([209.85.161.42:47316] helo=mail-fx0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8C/40-29697-04E73CE4 for ; Wed, 16 Nov 2011 04:11:28 -0500 Received: by faan2 with SMTP id n2so1273102faa.29 for ; Wed, 16 Nov 2011 01:11:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:reply-to:in-reply-to:references:from:date:message-id :subject:to:cc:content-type:content-transfer-encoding; bh=N1ek2WbmOsB96naabaEXY8KfKz3WtoayUI3ThzKQrq0=; b=e32QzFNljpLQJPgR0uxEJlMLGoAIfLxT53LfHOdMzo+I2kW+XOVvMFg/WdRZLFBH61 rstKuBbDd4kbhg7QqrCkra9tfpIIUBT/7ssX7D2GB+ct7PSTMrDr1RSzKn7XtPafrDb5 tkd+jkqhkiyKfE9YgRZQ2ODaB+C/DJnwswf+w= Received: by 10.182.12.66 with SMTP id w2mr3722480obb.7.1321434683075; Wed, 16 Nov 2011 01:11:23 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.29.202 with HTTP; Wed, 16 Nov 2011 01:11:02 -0800 (PST) Reply-To: RQuadling@GMail.com In-Reply-To: References: Date: Wed, 16 Nov 2011 09:11:02 +0000 Message-ID: To: Rasmus Schultz Cc: Stefan Marr , internals@lists.php.net Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] some notes about traits From: rquadling@gmail.com (Richard Quadling) On 16 November 2011 00:17, Rasmus Schultz wrote: > Here's a better example of something useful that actually works: > > =C2=A0trait Accessors > =C2=A0{ > =C2=A0 =C2=A0public function __get($name) > =C2=A0 =C2=A0{ > =C2=A0 =C2=A0 =C2=A0return $this->{'get'.$name}(); > =C2=A0 =C2=A0} > > =C2=A0 =C2=A0public function __set($name, $value) > =C2=A0 =C2=A0{ > =C2=A0 =C2=A0 =C2=A0$this->{'set'.$name}($value); > =C2=A0 =C2=A0} > =C2=A0} > > =C2=A0class OrderLine > =C2=A0{ > =C2=A0 =C2=A0use Accessors; > > =C2=A0 =C2=A0public $price; > =C2=A0 =C2=A0public $amount; > > =C2=A0 =C2=A0public function getTotal() > =C2=A0 =C2=A0{ > =C2=A0 =C2=A0 =C2=A0return $this->price * $this->amount; > =C2=A0 =C2=A0} > =C2=A0} > > =C2=A0$line =3D new OrderLine; > > =C2=A0$line->price =3D 20; > =C2=A0$line->amount =3D 3; > > =C2=A0echo "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 ... {'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} =3D $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 =3D $price; } protected function setAmount($amount) { $this->amount =3D $amount; } } $line =3D new OrderLine; $line->price =3D 20; $line->amount =3D 3; $line->tax =3D 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. --=20 Richard Quadling Twitter : EE : Zend : PHPDoc : Fantasy Shopper @RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY : bit.ly/lFnVea=C2=A0: fan.sh/6/370