从家长班级移除特质

时间:2018-11-30 08:06:49

标签: php cakephp cakephp-3.0 cakephp-3.6

这是场景

我有一个登录特征...

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的Controller ...

class UsersController extends BaseUserController {

     use MyLoginTrait;
}

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

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

2 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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();B::doIt一起使用,以调用相同的特征A方法-不必使用as“重命名”覆盖的方法。

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