Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP override trait method of parent class's trait

Tags:

php

I'm using Laravel 5.1 but this isn't specific to that framework, it's more of a general PHP question.

There's a parent class with traits specified:

namespace Illuminate\Foundation\Auth;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;

class User extends Model implements
  AuthenticatableContract,
  AuthorizableContract,
  CanResetPasswordContract {
    use Authenticatable, Authorizable, CanResetPassword;
}

Then I have the User class I'm concerned with extending from that:

namespace App\Api\V1\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\Traits\EntrustUserTrait;

class User extends Authenticatable {
  use EntrustUserTrait {
    EntrustUserTrait::can insteadof \Illuminate\Foundation\Auth\Access\Authorizable;
  }
}

The EntrustUserTrait has a can() method that conflicts with the Authorizable trait. However, the Authorizable trait is on the parent class, so this throws an error Required Trait wasn't added to App\Api\V1\Models\User.

I've searched around and there's plenty of information on overriding traits declared within the child class, but I can't seem to find anything about overriding traits from the parent class.

like image 738
jdforsythe Avatar asked Apr 05 '16 15:04

jdforsythe


1 Answers

Consider the following code:

<?php    
trait AA {
    function f() { 
        echo "I'm AA::f".PHP_EOL;
    }
}
class A {
    use AA;
}
trait BB {
    function f() { 
        echo "I'm BB::f".PHP_EOL;
    }
}
class B extends A {
    use BB;
}
$b = new B();    
$b->f();

I'm BB::f

I believe that traits work like copy-paste code. The trait code is treated like a "copy-pasted" code in the class it's used in so you can pretend that the trait is not really inherited but it's code is just part of the parent class.

like image 78
apokryfos Avatar answered Sep 28 '22 21:09

apokryfos