【问题标题】:Laravel use Trait methods in another TraitLaravel 在另一个 Trait 中使用 Trait 方法
【发布时间】:2019-05-16 16:00:01
【问题描述】:

通常我有一个关于某些东西不起作用的问题,现在我有一个关于某些东西起作用的问题,我只是对为什么感到困惑。这是我在 Laravel 中的结构:

示例控制器

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
   }

}

特征1

namespace App\Http\Traits;

trait Trait1 {
   exampleMethodTrait1()
   {
   }
}

特质2

namespace App\Http\Traits;

trait Trait2 {

   $test = $this->exampleMethodTrait1();

}

从 Trait2 调用 Trait1 中定义的方法确实有效,而我没有在 Trait2 中添加 use App\Http\Traits\Trait1;。是因为它们都加载在控制器中吗?

【问题讨论】:

    标签: php traits


    【解决方案1】:

    好的,让我输入相同的代码并解释它为什么起作用。

    特征1

    <?php
    namespace App\Http\Traits;
    
    trait Trait1 {
       public function exampleMethodTrait1()
       {
           echo 'okay';
       }
    }
    ?>
    

    特征 2

    <?php
    namespace App\Http\Traits;
    
    trait Trait2 {
        public function bar() {
            var_dump(get_class($this));
            $test = $this->exampleMethodTrait1();
        }
    }
    ?>
    

    我的控制器

    <?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();
        }
    }
    

    现在,如果您在 Trait 2 中注意到,var_dump(get_class($this)); $this 是 MyController 的实例,而不是 trait 2 的实例,这就是它的工作方式和预期行为。

    现在如果你想知道你是否可以在另一个方面使用一个特征

    你可以这样做 TaraitA

    Trait A {
    }
    

    特征B

    Trait B {
        use A;
    }
    

    它会正常工作的。

    【讨论】:

    • 感谢您的解释!当来自 Trait A 的方法已经在 Trait B 中可用时,我仍然对为什么我会在 Trait B 中执行 use A 感到困惑。
    • @eskimo 好的,为什么你认为它在另一个特征中可用,它是可用的类,执行从类开始,你正在使用类实例访问它们中的每一个,以防特征A,trait B,你不会在任何类中同时使用这两者,你会在类中使用 child trait。
    • 这就是我的问题所在;我怎么能从 trait2 中的 trait1 访问方法?我知道我可以在控制器的类中访问它们,因为我在那里加载它们。
    • @eskimo 为什么你认为你是在 trait 内部调用函数,而实际上是在类内部调用它。
    • Trait1Trait2 处于同一级别,即使您将它们放在另一个里面。 $this 是对您使用特征的类的实例的引用。
    【解决方案2】:

    是的,它们都作为控制器的一部分加载到您的控制器中,因此它们之间也可以访问控制器方法

    参见示例 4

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

    问候

    【讨论】:

      【解决方案3】:

      我认为您的困惑来自于相信特征中的$this 对应于特征本身。但事实并非如此。

      Traits 本身什么都不是:它们只存在于真实类的上下文中,作为 复制粘贴 方法的助手,但不会在视觉上污染您的实际类.

      你用来调用exampleMethodTrait1$this不是Trait2的实例(也不是Trait1),而是ExampleController的实例,它复制了从特征。

      这不仅发生在特征上,而且也发生在层次结构中的父类中:

      例子

      abstract class Base {}            // First level of inheritance
      class Building extends Base {}    // Second level of inheritance
      class House extends Building {}   // Last level of inheritance
      
      • $this(和static)始终对应于层次结构中最具体的类(继承的最后一层)的实例。
      • self 是指实际的 class 实例(与定义方法的继承级别相同)。仍然不是trait,它们不能被自己实例化。
      • 特征不是层次结构的一部分,而是盲目地粘贴在您use它们的位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-30
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-05
        相关资源
        最近更新 更多