How to check if a class uses a trait in PHP?

☆樱花仙子☆ 提交于 2020-02-21 10:09:16

问题


Notice that a trait may use other traits, so the class may not be using that trait directly. And also the class may be inherited from a parent class who is the one uses the trait.

Is this a question that can be solved within several lines or I would have to do some loops?


回答1:


The class_uses() function will return an array containing the names of all traits used by that class, and will work by passing it a class name or an instance.... however, you'd need to "recurse" through the inheritance tree to get all traits used, and through each trait as well

EDIT

Note that stealz at op dot pl has provided an example function showing how to do this recursion in the comments section of the linked PHP Docs page




回答2:


Check your trait in a trait list:

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

This return true or false if MyClass uses MyTrait




回答3:


Another way to approach this is to use interfaces that define what is expected of your traits. Then you are using "instanceof SomeInterface" instead of doing reflection or duck typing.




回答4:


The below function is from http://php.net/manual/en/function.class-uses.php, ulf's comment. Works perfect.

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);
}



回答5:


This is what I have in my Tools class

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



回答6:


Often, checking if the part of API you intend to use exists is a good enough substitute.
method_exists ( mixed $object , string $method_name ) : bool

Also, as @MeatPopsicle mentions, traits are often used in combination with (marker-)interfaces.



来源:https://stackoverflow.com/questions/46218000/how-to-check-if-a-class-uses-a-trait-in-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!