通常我对某些问题不满意,现在我对某些问题不满意,我只是对为什么感到困惑。这是我在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
}
}
特质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;
。那是因为它们都已加载到控制器中吗?
答案 0 :(得分:2)
好的,让我输入相同的代码并向您解释为什么它起作用。
特质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();
}
}
?>
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();
}
}
现在,如果您会在特性2中注意到,var_dump(get_class($this));
$这是MyController的实例,而不是特征2的实例,这就是它的工作方式和预期的行为。
现在,如果您想知道是否可以在另一个特性中使用一个特性
是
你可以喜欢 TaraitA
Trait A {
}
特质B
Trait B {
use A;
}
它将正常工作。
答案 1 :(得分:1)
是的,它们都作为控制器的一部分加载到您的控制器中,因此它们之间也可以访问控制器方法
请参阅示例4
https://www.php.net/manual/en/language.oop5.traits.php
致谢
答案 2 :(得分:0)
我认为您的困惑来自于认为特征内的 $this
对应于特征本身。但事实并非如此。
特征本身没什么:它们仅存在于真实类的上下文中,作为复制粘贴方法的辅助工具,但不会在视觉上污染您的实际类.
您用来调用 $this
的 exampleMethodTrait1
不是 Trait2
的实例(也不是 Trait1
),而是 {{1} 的实例}},这已经从特征中复制了方法。
这不仅发生在特征上,而且发生在层次结构中的父类中:
示例
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
它们的位置。