Traits

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Traits

Post by kaisellgren »

PHP 6 might get a new feature called "Traits". Basically it is used to split duplicate code:

Code: Select all

trait World
{
 public function World() {echo ' World!';}
}
class HelloWorld
{
 use World;
 public function SayIt() {echo 'Hello'; World();}
}
$hw = new HelloWorld;
$hw->SayIt(); // Hello World!
There's a lot of information here: http://wiki.php.net/rfc/traits

Anyway, my question here is about structuring traits in files. Just like with interfaces and exceptions, traits must be stored somewhere. It doesn't make sense to me to store these within existing classes, because traits are universally used, so, they need their own "location". I've been thinking about having a folder "Traits" and store all traits there, but this doesn't seem very good, because it would get messy if you have lots of trait files and there would be no clear logic in the way there are located which makes e.g. autoloading painful. I think one must store traits in separate PHP files. I think it's gonna be either one trait per file or one trait category per file, but the real question is: where would these trait files be stored? Also, there should be a handy way to autoload traits... if autoload is even going to support traits?

It would be much easier if there was an existing PHP project using traits, but I can't find any (and I can understand why).
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Traits

Post by Jenk »

As a Squeak developer, I've used traits lots, and for those unfamiliar with the concept, they quite literally are plug-n-play components. Easiest way to describe/summarise them is "interfaces with functionality attached." The only downfall with Traits is that they are stateless, so if your Trait's behaviour requires state, the classes that use them must implement an instance variable specifically for them, and provide accessors for them.

So to that end.. logically, you'd categorise them like an interface or class, i.e. by their behaviour. Perhaps /Project/DataLayer/HasDBConnection.php for an example of the following:

Code: Select all

trait HasDBConnection {
  public function getConnection() {
    throw new NotImplementedException();
  }
 
  public function setQuery($string) {
    $this->getConnection()->prepareStatement($string);
  }
}

Code: Select all

class Foo {
  use HasDBConnection;
  public $dbConnection;
  public function __construct($db) {
    $this->dbConnection = $db;
  }
  public function getConnection() {
    return $this->dbConnection;
  }
}
Traits are simply the best way to use Composite objects, and I'm quite pleased PHP are assessing them. :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Traits

Post by alex.barylski »

Interesting...never heard of traits before...I'm reading a paper on them right now. Very cool, PHP should absolutely adopt them.

1. Drop namespaces (I think prefixing the class name with the Vendor_Project_Package_X provides significant protection from namespace collision).

2. Implement operator overloading and traits. :D

Cheers,
Alex
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Traits

Post by kaisellgren »

Yes, interesting indeed. I've been scrutinizing the PHP 6 source code for a good number of days and I must say there's a lot happening under the hood and I simply love the full Unicode awareness which is neatly adopted everywhere in the core functionality of PHP. :)

Another interesting thing is the upload progress feature and there might be a cranky feature called Taint. Taints, which I genuinely believe to be very tumbledown, are supposed to stop XSS, SQLi, and other such injection vulnerabilities. Good luck..

I am looking forward to traits. Any ideas when PHP 6 could come out? 2011? :roll:
User avatar
Darhazer
DevNet Resident
Posts: 1011
Joined: Thu May 14, 2009 3:00 pm
Location: HellCity, Bulgaria

Re: Traits

Post by Darhazer »

Code reuse is one of the main goals that object-oriented languages try to achieve with inheritance. Unfortunately, single inheritance often forces the developer to take a decision in favor for either code reuse *or* conceptual clean class hierarchies. To achieve code reuse, methods have either to be duplicated or to be moved near the root of the class hierarchy, but this hampers understandability and maintainability of code.
Actually there is why one of the principles of OO Design is: prefer composition instead of inheritance.
And in my opinion, the trails are useless and they just break the OOP. And what exactly is the difference between Trail and a function, declared in a namespace :mrgreen:

Just my opinion on the topic....
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Traits

Post by Christopher »

Darhazer wrote:Actually there is why one of the principles of OO Design is: prefer composition instead of inheritance.
And in my opinion, the trails are useless and they just break the OOP. And what exactly is the difference between Trail and a function, declared in a namespace :mrgreen:

Just my opinion on the topic....
I think maybe you are misunderstanding Traits. They provide a limited form of multiple inheritance similar to Mixins. They can certainly be very useful when use properly.
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Traits

Post by alex.barylski »

Unicode awareness which is neatly adopted everywhere in the core functionality of PHP.
Yes, that'll be nice too. :)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Traits

Post by Jenk »

Darhazer wrote:
Code reuse is one of the main goals that object-oriented languages try to achieve with inheritance. Unfortunately, single inheritance often forces the developer to take a decision in favor for either code reuse *or* conceptual clean class hierarchies. To achieve code reuse, methods have either to be duplicated or to be moved near the root of the class hierarchy, but this hampers understandability and maintainability of code.
Actually there is why one of the principles of OO Design is: prefer composition instead of inheritance.
And in my opinion, the trails are useless and they just break the OOP. And what exactly is the difference between Trail and a function, declared in a namespace :mrgreen:

Just my opinion on the topic....
Because a function is not attached to an object. A Trait is. See my example for the difference between a function and a trait.
User avatar
Darhazer
DevNet Resident
Posts: 1011
Joined: Thu May 14, 2009 3:00 pm
Location: HellCity, Bulgaria

Re: Traits

Post by Darhazer »

Jenk wrote:Because a function is not attached to an object. A Trait is. See my example for the difference between a function and a trait.
I meant the example in the first post, when the trail is used within the class method. As far as I understand trails, actually the class will have the method World(), is that correct?

And yeah, after reading the documentation of the PHP trails, I still think that with proper design you don't need them and there are other OO techniques to create class that have the functionality of 2 other classes.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Traits

Post by Jenk »

It's Trait, not Trail.

And yes, there are other ways, but Traits make it easier to breakdown and reuse code. Instead of Composite objects containing many objects, you've just got one object made of fragments of objects, which is what a Trait is. It also means you can override/extend behaviour of many objects in one place when needed.. something you can't do with class inheritance.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Traits

Post by Christopher »

I think it is going to be handy in cases where you have to Proxy a large interface with many methods like this:

Code: Select all

public function Bar($baz) {
     return $this->foo->Bar($baz);
}
It is simply tedious, and adds call overhead, when you are forced to Proxy an interface because the class as already extend a different class.
(#10850)
User avatar
Darhazer
DevNet Resident
Posts: 1011
Joined: Thu May 14, 2009 3:00 pm
Location: HellCity, Bulgaria

Re: Traits

Post by Darhazer »

arborint wrote:I think it is going to be handy in cases where you have to Proxy a large interface with many methods like this:

Code: Select all

public function Bar($baz) {
     return $this->foo->Bar($baz);
}
It is simply tedious, and adds call overhead, when you are forced to Proxy an interface because the class as already extend a different class.
Such proxy can be coded via __call() magic method?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Traits

Post by Christopher »

Darhazer wrote:Such proxy can be coded via __call() magic method?
Sure, but it's still a proxy and it still has similar tedious coding to support. And even more overhead because __call() is an error handler. And say you only want 8 of the 10 methods supported. Or if the interface to the Proxied class changes and you had to do tricks in __call(). Or it is a library class and you want the programmer to be able to implement their own __call() method. Certainly __call() is handy (even if it is hackish), but that does not mean that Traits are now...
(#10850)
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Traits

Post by omniuni »

Granted this is a limited assessment, but it would seem that a trait is an elegant way of handling what would previously have required a "magic" method. Magic is nice, but really it's just a hack around. If something is explicitly coded, it should mean vast speed improvements, more elegant end usage, and generally more accessible code, since less is being done by "magic" and rather by explicit use. Generally, I like the idea, and I'm excited for PHP6!
User avatar
Darhazer
DevNet Resident
Posts: 1011
Joined: Thu May 14, 2009 3:00 pm
Location: HellCity, Bulgaria

Re: Traits

Post by Darhazer »

Do you know if traits will work like interfaces, I mean "instanceof traitName" or function something(traitName $param)?

P.S. In the newer RFC there are also Grafts
Post Reply