重写 Doctrine Trait 属性

Overriding Doctrine Trait Properties

我知道您可以通过在 class 中声明来覆盖 trait 方法 ,我很好奇是否可以覆盖 trait属性同理。这样做安全吗?它不在文档中,所以我犹豫是否要实现它。

来自文档

An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.

http://php.net/manual/en/language.oop5.traits.php

您可以在 class 中声明 trait 属性,但必须保持与 trait 相同的定义。它不能被不同的定义覆盖。因此,由于您已经可以访问 class 中的 trait 属性,因此不需要再次重新定义。认为 trait 作为复制粘贴代码。

<?php
trait FooTrait 
{
    protected $same       = '123';
    protected $mismatch  = 'trait';
}

class FooClass 
{
    protected $same      = '123';

    // This override property produces: 
    // PHP Fatal error:  FooClass and FooTrait define the same property
    // ($mismatchValue) in the composition of FooClass. However, the definition
    // differs and is considered incompatible
    protected $mismatch  = 'class';

    use FooTrait;
}

您不能在使用特征的 class 中覆盖特征的 属性。但是,您可以在扩展 class 的 class 中覆盖使用该特征的 属性 。例如:

trait ExampleTrait
{
    protected $someProperty = 'foo';
}

abstract class ParentClass
{
    use ExampleTrait;
}

class ChildClass extends ParentClass
{
    protected $someProperty = 'bar';
}

我的解决方案是使用构造函数,例如:

trait ExampleTrait
{
    protected $someProperty = 'foo';
}

class MyClass
{
    use ExampleTrait;

    public function __construct()
    {
         $this->someProperty = 'OtherValue';
    }
}

另一种解决方案,在本例中使用 属性 updatable

当 属性 仅在特征的方法中需要时,我使用它...

trait MyTrait
{
    public function getUpdatableProperty()
    {
        return isset($this->my_trait_updatable) ?
            $this->my_trait_updatable:
            'default';
    }
}

...并在 class.

中使用特征
class MyClass
{
    use MyTrait;

    /**
     * If you need to override the default value, define it here...
     */
    protected $my_trait_updatable = 'overridden';
}