如何检查类是否在PHP中使用特征?

bij*_*ngo 8 php traits

请注意,特征可能使用其他特征,因此该类可能不会直接使用该特征.并且该类可以从使用该特征的父类继承.

这是一个可以在几行内解决的问题,还是我必须做一些循环?

Ken*_*Ken 18

如果有人在使用 Laravel 框架时遇到这个问题,那么它有一个名为class_uses_recursive().

https://laravel.com/docs/8.x/helpers#method-class-uses-recursive


小智 18

如果您只想检查您可以使用的类,class_uses它将返回仅由该类使用的所有特征的数组

in_array(SoftDeletes::class, class_uses(Model::class), true) //return boolean
Run Code Online (Sandbox Code Playgroud)

如果你想检查该类或其父类是否使用该特征,请使用class_uses_recursive

in_array(SoftDeletes::class, class_uses_recursive(Model::class), true) //return boolean
Run Code Online (Sandbox Code Playgroud)


Mea*_*cle 11

解决此问题的另一种方法是使用定义对您的特征的期望的接口。然后您使用“instanceof SomeInterface”而不是进行反射或鸭子输入。


Mar*_*ker 9

class_uses()函数将返回包含由类使用的所有特征的名称的数组,并且将传递一个类名或实例工作....但是,你需要"递归",通过继承树获得所有使用的特征,并通过每个特征

编辑

请注意,stealz at op dot pl它提供了一个示例函数,显示如何在链接的PHP Docs页面的comments部分中执行此递归


Dav*_*zes 6

在特征列表中检查您的特征:

$usingTrait = in_array( MyTrait::class, array_keys((new \ReflectionClass(MyClass::class))->getTraits()) );

如果MyClass使用MyTrait,则返回true或false

  • 为什么不只是`class_uses`而不是反射? (3认同)
  • $usingTrait = in_array(MyTrait::class, class_uses(MyClass::class)) (2认同)

inf*_*.de 6

通常,检查您打算使用的 API 部分是否存在是一个足够好的替代方案。
method_exists ( mixed $object , string $method_name ) : bool

此外,正如 @MeatPopsicle 提到的,特征通常与(标记)接口结合使用。


bij*_*ngo 5

下面的函数来自http://php.net/manual/en/function.class-uses.php,ulf的评论。作品完美。

function class_uses_deep($class, $autoload = true)
{
    $traits = [];

    // Get traits of all parent classes
    do {
        $traits = array_merge(class_uses($class, $autoload), $traits);
    } while ($class = get_parent_class($class));

    // Get traits of all parent traits
    $traitsToSearch = $traits;
    while (!empty($traitsToSearch)) {
        $newTraits = class_uses(array_pop($traitsToSearch), $autoload);
        $traits = array_merge($newTraits, $traits);
        $traitsToSearch = array_merge($newTraits, $traitsToSearch);
    };

    foreach ($traits as $trait => $same) {
        $traits = array_merge(class_uses($trait, $autoload), $traits);
    }

    return array_unique($traits);
}
Run Code Online (Sandbox Code Playgroud)