Laravel 在另一个 Trait 中使用 Trait 方法

Laravel use Trait methods in another Trait

通常我会问一些不工作的问题,现在我会问一些正在工作的问题,我只是不知道为什么。这是我在 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;。是因为它们都加载到控制器中了吗?

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

见例4

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

此致

好的,让我放上相同的代码并向您解释它为什么有效。

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

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

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

你可以这样做 TaraitA

Trait A {
}

特质B

Trait B {
    use A;
}

它会很好地工作。

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

特征本身什么都不是:它们仅存在于真实的上下文中 class,作为 复制粘贴 方法,但不会在视觉上污染您的实际 classes.

您用来调用 exampleMethodTrait1$this 不是 Trait2(也不是 Trait1)的一个实例,而是一个ExampleController 的实例,它从特征中复制了方法。

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

例子

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)总是对应于层次结构(最后一层继承)中最具体的class实例。
  • self 而是指实际的 class 实例(与定义方法的继承级别相同)。仍然不是 trait,它们不能被自己实例化。
  • 这些特征不是层次结构的一部分,而是盲目地粘贴在您use它们的位置。