1

Here is the scenario

I have a Login Trait...

trait LoginTrait {

     public function login() {

         // some login code here
     }

     public function someOtherFunction() {

         // some elite code here
     }
}

I have a Base (Parent) Controller...

class BaseUserController {

    use LoginTrait;
}

I have another trait where I am overriding the login function...

trait MyLoginTrait {

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

     public function login() {

          // some new elite login code
     }
 }

I have a Controller that extends the BaseUsersController...

class UsersController extends BaseUserController {

     use MyLoginTrait;
}

My question is, How do I remove the LoginTrait from the BaseUserController?

Right now, I am attempting to login and the login function from LoginTrait is firing, not MyLoginTrait which has the new login function...

Jeffrey L. Roberts
  • 2,844
  • 5
  • 34
  • 69

2 Answers2

1

This might help you on your way

<?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()

OR USE:

class UsersController extends BaseUserController
{
    use LoginTrait, MyLoginTrait {
        MyLoginTrait::login insteadof LoginTrait;
    }
}

$user = new UsersController();
$user->login(); // output: in MyLoginTrait::login()
lovelace
  • 1,195
  • 1
  • 7
  • 10
1

Most likely your problem is at a different spot. Overwriting inherited traits with other traits works like is should:

<?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();

Output (PHP 7.2): DoIt from B.

You can even use parent::doIt(); withing B::doIt for called the same method of trait A - without having to "rename" the overwritten method using as.

To answer your question directly: You cannot "remove" the trait from the super class - you have to live with the inherited method but you can overwrite it. Alternative: change your inheritance hierarchy.