从父类中删除特性



这是的场景

我有一个登录特性。。。

trait LoginTrait {
public function login() {
// some login code here
}
public function someOtherFunction() {
// some elite code here
}
}

我有一个基本(父(控制器。。。

class BaseUserController {
use LoginTrait;
}

我还有一个特点,就是我正在覆盖登录功能。。。

trait MyLoginTrait {
use LoginTrait {
TraitsLoginTrait::login as oldLogin;
}
public function login() {
// some new elite login code
}
}

我有一个扩展BaseUsersController的控制器。。。

class UsersController extends BaseUserController {
use MyLoginTrait;
}

我的问题是,如何从BaseUserController中删除LoginTait?

现在,我正在尝试登录,LoginTait的登录功能正在启动,而不是具有新登录功能的MyLoginTrait。。。

这可能会帮助您实现

<?php
trait LoginTrait
{
public function login()
{
echo 'in LoginTrait::login()' . '<br />';
// some login code here
}
public function someOtherFunction()
{
// some elite code here
}
}
trait MyLoginTrait
{
public function login()
{
echo 'in MyLoginTrait::login()' . '<br />';
// some new elite login code
}
}
class BaseUserController
{
use LoginTrait;
}
class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login as myLogin;
LoginTrait::login insteadof MyLoginTrait;
}
}
$user = new UsersController();
$user->login();// output: in LoginTrait::login()
$user->myLogin();// output: in MyLoginTrait::login()

或使用:

class UsersController extends BaseUserController
{
use LoginTrait, MyLoginTrait {
MyLoginTrait::login insteadof LoginTrait;
}
}
$user = new UsersController();
$user->login(); // output: in MyLoginTrait::login()

您的问题很可能在另一个地方。将遗传特征与其他特征叠加就像应该的一样:

<?php
trait A
{
public function doIt()
{
echo "DoIt from A." . PHP_EOL;
}
}
trait B
{
public function doIt()
{
echo "DoIt from B." . PHP_EOL;
}
}
class X
{
use A;
}
class Y extends X
{
use B;
}
$foo = new Y();
$foo->doIt();

输出(PHP 7.2(:DoIt from B.

您甚至可以在B::doIt中使用parent::doIt();来调用特征A的相同方法,而不必使用as"重命名"覆盖的方法。

直接回答你的问题:你不能从超类中"移除"trait-你必须使用继承的方法,但你可以覆盖它。替代方案:更改继承层次结构。

最新更新