我有2个类和特质:
TraitRunner.php
use Traits\Create;
class TraitRunner {
...
}
Controller.php这样
use TraitRunner;
class Controller {
public function __construct()
...
$this->something = app()->make(TraitRunner()::class);
...
}
}
FooController.php
use Controller;
class FooController extends Controller {
...
}
我需要覆盖特征方法。我可以创建一个新的特性并编辑TraitRunner.php,添加:
use Create, MyCreate {
MyCreate::fooMethod insteadof Create;
}
特征方法的实际使用在代码中更深处,因此我将其简化为清晰。
问题是我无法更改 TraitRunner.php 和 Controller.php 文件,因为它们位于供应商目录中。如果我只能编辑 FooController.php ,请建议我添加的内容和位置。
答案 0 :(得分:1)
其他特征是否覆盖了特征? 是!不,如果做错了; - )
trait t1 {
function abc(){
print __METHOD__.'<br>';
}
}
class a {
use t1;
}
trait t2 {
function abc(){
print __METHOD__.'<br>';
//parent::abc(); //will call t1:abc() again, if exists and is called
}
}
class b extends a {
use t2;
}
//works
(new a)->abc();//prints t1::abc<br>
//works
(new b)->abc();//prints t2::abc<br>
//But this wont work. (Did not realay know why)
class c {
use t1,t2;
}
//So this fails (both traits are used in the same class definition)
(new c)->abc();
//Fatal error: Trait method abc has not been applied, because there are collisions
特征可以实现其他特征。
trait t1 {
function x(){}
}
trait t2 {
use t1;
function x(){}
}
度过愉快的一天
答案 1 :(得分:0)
您不需要创建差异特征来覆盖特征中的方法。
来自PHP Doc:
优先顺序是当前类的成员覆盖 特征方法,反过来覆盖继承的方法。
所以,例如,这段代码:
trait TraitRunner {
public function sayHello() {
echo 'TraitRunner method';
}
}
class Controller {
use TraitRunner;
}
class FooController extends Controller {
public function sayHello() {
echo 'FooController method ';
}
}
$o = new FooController();
$o->sayHello();
会给:
FooController method
答案 2 :(得分:0)
通过实验,我发现了这种方法:
1.-使用覆盖方法fooMethod
创建一个新的特征MyCreate2.-编辑FooController.php:
use vendor\Traits\Create
use app\Traits\MyCreate
class TraitRunner extends vendor\TraitRunner {
use Create, MyCreate {
MyCreate::fooMethod insteadof Create;
}
}
class Controller extends vendor\Controller {
// the following code is the place where TraitRunner is used, so we have to put it here
public function __construct()
...
$this->something = app()->make(TraitRunner()::class);
...
}
}
class FooController extends Controller { ...
如果有更充分的方式,欢迎您提出建议。虽然这种方式很有效。