如何将PHP traits限制在特定的类中

tmb3ates  于 2023-06-28  发布在  PHP
关注(0)|答案(2)|浏览(60)

我有以下特点:

trait ARCacheableTrait
{
    public function instantiate() {
        // this will need to call some ActiveRecord methods using parent::
    }
}

它的目的是覆盖ActiveRecord类的instantiate方法。什么是确保它只应用于此类类的正确方法?我想抛出一个异常,如果有人试图将它添加到类,不是或不扩展ActiveRecord或更好,确保类型安全抛出编译时错误...

shyt4zoc

shyt4zoc1#

最好的方法是使用abstract方法定义来对展示类施加要求:

trait ARCacheableTrait {

    public function instantiate() {
        parent::foo();
    }

    abstract public function foo();

}

这迫使展示类实现一个方法foo,以确保trait可以调用它。然而,没有办法限制一个特性只在某个类 * 层次结构 * 中显示。如果你想这样做,你可能想实现一个特定的ActiveRecord子类,它实现了这个特定的instantiate行为,而不是使用trait。

wecizke3

wecizke32#

就我个人而言,我在每个Trait方法之前调用一个check方法:

trait ARCacheableTrait
{
    public function instantiate()
    {
        static::canUseTraitARCacheableTrait();
        // this will need to call some ActiveRecord methods using parent::
    }

    private static function canUseTraitARCacheableTrait()
    {
        static $isCorrectClass;

        $isCorrectClass = $isCorrectClass ?? is_a(static::class, ActiveRecord::class, true);
        if (!$isCorrectClass) {
            throw new LogicException(
                sprintf(
                    'Only classes that inherit %s may use %s trait. The %s class cannot use it',
                    ActiveRecord::class,
                    __TRAIT__,
                    static::class
                )
            );
        }
    }
}

这种解决方案的缺点是,只有在调用某个方法后才会引发异常。
另一方面,相对于“deceze”提出的优点是,Trait决定谁可以使用它。你不需要在每个类中添加“foo”方法的实现,事实上,“foo”的实现并不能清楚地表明它是正确的类。

相关问题