How to use Traits in PHP?

Asked

Viewed 1,084 times

10

I’m creating namespaces for my traits and using them directly, without using them within a specific class, example:

NOTE: The code below is just an example.

namespace Decrypt;

trait Rc4 {

    public function nome()
    {
        return "Fulano";
    }
}

So I call them directly like this:

use Decrypt\Rc4;

echo Rc4::nome();

I can use the traits that way? That’s right?

Even if I can’t do it, or even if one trait cannot exist without a class, I can group them into one namespace to use in different classes, but sharing some equal functionality?

  • 3

    The first question you should ask is why you are doing this. Why not use the right mechanism? If you really have a reason to do this, you tried, it worked?

  • 4

    Trait is a form of structuring for related and independent business rules. By definition, a trait should not exist without a class, because the first defines the behavior of the second, so I believe that no, you should not do this.

  • 1

    I understood that this is why I created the traits, because some classes needed new functionalities and I realized that these functionalities could exist in other classes, which is what really happened, only I used them independently of the classes, so now I’m gonna fix it.

  • I also realized that we can not group them in a namespace if we have to give a use in the trait within the class.

2 answers

15


Just like the @Anderson Carlos Woss has already commented and has practically answered your questions, I will make an addendum as you can read in documentation:

What are Traits?

Traits are mechanisms for reusing code in single inheritance languages.

They should be used where there are no relations and cannot/should extend/inherit from another class. Using the example of Thiago Belem , imagine a feature of log, where you would usually create a class to manipulate this:

class Log {
    public function log($message) {
        // Salva $message em um log de alguma forma
    }
}

And to use it, you would do something like:

class Usuario extends Model {

    protected $Log;

    public function __construct() {
        $this->Log = new Log();
    }

    public function save() {
        // Salva o usuário de alguma forma
        // ...

        // Salva uma mensagem de log
        $this->Log->log('Usuário criado');
    }

}

See the work you need to use this feature, when you could simplify using Traits:

trait Log {

    public function log($message) {
        // Salva $message em um log de alguma forma
    }

}

Defining the behavior in the class:

class Usuario extends Model {

    use Log;

    public function save() {
        // Salva o usuário de alguma forma
        // ...

        // Salva uma mensagem de log
        $this->log('Usuário criado');
    }

}

Answering your own questions:

I can wear the traits like this ?

If the language allows to use this is one thing, if MUST is another totally different. And for the second option, it is nay.

that is correct ?

No, it is not correct. In the documentation itself it says that it is not possible to instance it on its own.

Read on Horizontal Reuse to understand a little better what is proposed with the use of Traits.

14

There’s a question here that talks about the basics of trait. And also when choosing to use each structure.

PHP actually allows you to use trait directly, but this is conceptually wrong. It’s PHP being PHP. It’s known that the language never used correct concepts. So you can use, nothing prevents, but if you will use a sophisticated feature it is better to use it as it was thought.

Trait is for adding functionality to a class, not for replacing classes.

In fact, the example used is so simple that if you’re going to do this, there shouldn’t even be class. I know it might just be an example, but in this one, it’s not necessary. It is common for people to want to encapsulate functions within classes to say they are doing OOP. OOP has nothing to do with putting everything into classes. And OOP alone does not guarantee code to be better, on the contrary. I’m going to repeat a phrase here that people liked: OOP is like teenage sex, everyone says it does, but do even few do. If you want to do understand the concept well, and almost nobody understands, few teach right, and then you will know why the trait is useful.

Just create trait when it is the best possible tool. It may be that an interface is the best option, it may be that an abstract class is the best option, or it may not even need that. Do not create one to use in zero classes, do not create to use in a class.

If you already abuse class inheritance you will probably abuse the inheritance of traits. I realize that in PHP is where most abuse of inheritance violating in full the liskov principle. Of course the trait can even be a salvation since his intention is to add a feature, which can solve the issue of mistaken inheritance. But consider that this feature should be in a totally separate class, obeying the principle of single responsibility.

The basic difference of the interface and trait is that the first provides only one contract, and the second also provides a standard implementation for the contract set out there.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.