2

In Laravel, I have a class User that extends Authenticatable and uses a trait called Activable:

class User extends Authenticable {

    use Activable;

    protected $is_active_column = 'is_active';

}

trait Activable {

    /**
     * The name of the column with the activable status
     *
     * @var string
     */
    protected $is_active_column = 'is_active';

}

When I try to find a User in tinker I get this error:

[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.

PHP Fatal error:  App\Models\User and App\Traits\Activable define the same property ($is_active_column) in the composition of App\Models\User. However, the definition differs and is considered incompatible.
Superveci
  • 51
  • 4

1 Answers1

2

This is intended behavior. The PHP documentation on Traits is explicit about this

Properties

Traits can also define properties.

Example #12 Defining Properties

<?php
trait PropertiesTrait {
    public $x = 1;
}

class PropertiesExample {
    use PropertiesTrait;
}

$example = new PropertiesExample;
$example->x;
?>

If a trait defines a property then a class can not define a property with the same name unless it is compatible (same visibility and initial value), otherwise a fatal error is issued.

Example #13 Conflict Resolution

<?php
trait PropertiesTrait {
    public $same = true;
    public $different = false;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true;
    public $different = true; // Fatal error
}
?>
IGP
  • 14,160
  • 4
  • 26
  • 43
  • 1
    Ok, perfect, but how do I create a property in a trait that can be overriden by the class? – Superveci Mar 04 '22 at 21:03
  • 1
    I suppose setters? Or trying to set them in a constructor? – IGP Mar 04 '22 at 22:37
  • OR alternatively, not using traits to override properties. – IGP Mar 04 '22 at 22:50
  • Or inherits a dummy abstruct class which using this trait: https://stackoverflow.com/questions/32571920/overriding-doctrine-trait-properties/38558480#38558480 – n0099 Jul 04 '23 at 09:19