0

这是场景

我有一个登录特征...

trait LoginTrait {

     public function login() {

         // some login code here
     }

     public function someOtherFunction() {

         // some elite code here
     }
}

我有一个基本(父)控制器......

class BaseUserController {

    use LoginTrait;
}

我有另一个特征,我正在覆盖登录功能......

trait MyLoginTrait {

     use LoginTrait {
          Traits\LoginTrait::login as oldLogin;
     }

     public function login() {

          // some new elite login code
     }
 }

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

class UsersController extends BaseUserController {

     use MyLoginTrait;
}

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

现在,我正在尝试登录,并且 LoginTrait 的登录功能正在触发,而不是具有新登录功能的 MyLoginTrait...

4

2 回答 2

1

这可能会对您有所帮助

<?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()
于 2018-11-30T09:29:36.167 回答
1

您的问题很可能出在不同的位置。用其他特征覆盖继承的特征就像应该:

<?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.

您甚至可以使用parent::doIt();withing B::doItfor 调用相同的 trait 方法A- 无需使用as.

直接回答您的问题:您不能从超类中“删除”该特征 - 您必须使用继承的方法,但您可以覆盖它。替代方案:更改您的继承层次结构。

于 2018-11-30T09:39:33.100 回答