How to use Traits in PHP?

7

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

OBS: 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();

Can I use traits this way? Is that correct?

Even though I can not do this, even though a trait can not exist without a class, I can group them into a namespace to use in different classes , but do you share some of the same functionality?

    
asked by anonymous 10.07.2017 / 13:58

2 answers

10

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

What are Traits ?

  

Traits are mechanisms for code reuse in unique inheritance languages.

They should be used where there are no relationships and can not extend / inherit from another class. Using the example of Thiago Belem , imagine a feature of log , where you would usually create a class for 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 have 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 behavior in 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');
    }

}

Responding to your questions:

  

Can I use traits like this?

If language allows you to use it like that, it is something totally different. And for the second option, it's not .

  

Is this correct?

No, it is not correct. In the documentation itself says that you can not instantiate it on your own.

Read Horizontal Reuse to get a little better understanding of what you are proposing with Traits .

    
10.07.2017 / 14:45
12

There is a question here that talks about the basics of trait . And also when you choose to use each framework .

PHP actually allows you to use trait directly, but this is conceptually wrong. It is PHP being PHP. It is well known that language has 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 meant to add functionality to a class, not to replace classes.

In fact, the example used is so simple that if it is to do this, neither class should exist. I know it may just be an example, but this one is 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 by itself does not guarantee code to be better, on the contrary. I will repeat a phrase here that the people liked: OOP is like teenage sex, everyone says it does, but doing even few do. If you want to understand the concept well, and almost nobody understands, few teach right, and then you will know why trait is useful.

Just create trait when it is the best tool possible. 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 it. 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 it is where you most have inheritance abuse by violating the Liskov principle >. Of course, trait may even be a salvation since its intent is to add a feature, which can solve the issue of wrong inheritance. But consider that this functionality should be in a totally separate class, obeying the principle of single responsibility .

The basic interface and trait difference is that the first provides only one contract, and the second one also provides a default implementation for the contract established there.

    
10.07.2017 / 14:47