问题
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