1

Normally I have a question about something not working, now I have a question about something that IS working, I am just confused as to why. This is the structure that I have in Laravel:

ExampleController

use App\Http\Traits\Trait1;
use App\Http\Traits\Trait2;

ExampleController extends Controller {

   use Trait1, Trait2;

   public function index()
   {
      // I can use methods from Trait1 and Trait2 here, works fine
   }

}

Trait1

namespace App\Http\Traits;

trait Trait1 {
   exampleMethodTrait1()
   {
   }
}

Trait2

namespace App\Http\Traits;

trait Trait2 {

   $test = $this->exampleMethodTrait1();

}

Calling a method defined in Trait1 from Trait2 actually works, while I have not added use App\Http\Traits\Trait1; in Trait2. Is that because they are both loaded in the controller?

3 Answers 3

2

Okay, Let me put same code and explain you why it is working.

Trait1

<?php
namespace App\Http\Traits;

trait Trait1 {
   public function exampleMethodTrait1()
   {
       echo 'okay';
   }
}
?>

Trait 2

<?php
namespace App\Http\Traits;

trait Trait2 {
    public function bar() {
        var_dump(get_class($this));
        $test = $this->exampleMethodTrait1();
    }
}
?>

MyController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Traits\Trait1;
use App\Http\Traits\Trait2;

class MyController extends Controller
{
    use Trait1, Trait2;


    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $this->bar();
    }
}

Now, if you will notice in Trait 2, var_dump(get_class($this)); $this is instance of MyController and not instance of trait 2, that is how it is working and it is expected behavior.

Now if you want to know if you can use one trait in side another

YES

You can do like TaraitA

Trait A {
}

TraitB

Trait B {
    use A;
}

And it will work fine.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks for the explanation! I'm still confused as to why I would do use A in Trait B when the method from Trait A is already available in Trait B.
@eskimo okay, why you are thinking it is available in another trait, it is available is the class, the execution starts from class and you are accessing each of them with class instance, in case of trait A, trait B, you will not use both in any class, you will use the child trait in class.
This is what my question is about; how come can I access a method from trait1 in trait2? I understand I can access them in the class in the controller because I load them there.
@eskimo Why you are thinking you are calling the function inside the trait, while you are actually calling it inside the class.
Trait1 & Trait2 are at the same level, even if you put them one inside the other. $this is a reference to the instance of the class where you use the traits.
|
1

Yes, they are both loaded in your controller as a part of it therefore they have access between them also controller methods

See the example 4

https://www.php.net/manual/en/language.oop5.traits.php

Regards

Comments

0

I think your confusion comes from believing that the $this inside a trait corresponds to the trait itself. But it is not.

Traits are nothing by themselves: they exists only in the context of a real class, as a helper to copy-paste methods around but not visually polluting your actual classes.

The $this you use to call exampleMethodTrait1 is not an instance of Trait2 (nor Trait1) but an instance of ExampleController, that has copied the methods over from the traits.

This doesn't happen only with traits, though, but also with parent classes in the hierarchy:

Example

abstract class Base {}            // First level of inheritance
class Building extends Base {}    // Second level of inheritance
class House extends Building {}   // Last level of inheritance
  • $this (and static) always corresponds to an instance of the most concrete class of the hierarchy (the last level of inheritance).
  • self instead refers to the actual class instance (the same level of inheritance where the method is defined). Still never a trait, they cannot be instantiated by themselves.
  • the traits are not part of the hierarchy, but blindly pasted where you use them.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.