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

时间:2017-09-14 11:33:07

标签: php traits

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

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

8 个答案:

答案 0 :(得分:7)

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

修改

请注意,string myFormat = dt.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture); 提供了一个示例函数,显示如何在链接的PHP文档页面的评论部分中执行此递归

答案 1 :(得分:5)

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

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

如果 MyClass 使用 MyTrait

,则返回true或false

答案 2 :(得分:4)

如果任何人在使用Laravel框架时遇到此问题,则该函数具有名为NewsItem的帮助程序功能。

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

答案 3 :(得分:2)

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

答案 4 :(得分:1)

这是我的“工具”课程中的内容

static function 
isTrait( $object, $traitName, $autoloader = true )
{
    $ret = class_uses( $object, $autoloader ) ;
    if( is_array( $ret ) )
    {
        $ret = array_search( $traitName, $ret ) !== false ;
    }
    return $ret ;
}

答案 5 :(得分:0)

以下功能来自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);
}

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

in_array(SoftDeletes::class, class_uses(Model::class), true) //return boolean

如果您想检查类或其父类是否使用 trait,请使用 class_uses_recursive

in_array(SoftDeletes::class, class_uses_recursive(Model::class), true) //return boolean