Notez qu'un trait peut utiliser d'autres traits, donc la classe peut ne pas utiliser directement ce trait. Et la classe peut également être héritée d'une classe parente qui est celle qui utilise le trait.
Est-ce une question qui peut être résolue en plusieurs lignes ou je devrais faire des boucles?
La fonction class_uses () retournera un tableau contenant les noms de tous les traits utilisés par cette classe, et fonctionnera en lui passant un nom de classe ou une instance .... cependant, vous devrez "recurse" à travers l'arbre d'héritage pour obtenir tous les traits utilisés, et à travers chaque trait aussi
[~ # ~] modifier [~ # ~]
Notez que stealz at op dot pl
a fourni un exemple de fonction montrant comment effectuer cette récursivité dans la section commentaires de la page de documentation PHP Docs
Vérifiez votre trait dans une liste de traits:
$usingTrait = in_array( MyTrait::class, array_keys((new \ReflectionClass(MyClass::class))->getTraits()) );
Cela retourne vrai ou faux si MyClass utilise MyTrait
Une autre façon d'aborder cela est d'utiliser des interfaces qui définissent ce que l'on attend de vos traits. Ensuite, vous utilisez "instanceof SomeInterface" au lieu de faire de la réflexion ou de la frappe de canard.
La fonction ci-dessous provient de http://php.net/manual/en/function.class-uses.php , commentaire d'ulf. Fonctionne parfaitement.
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);
}
C'est ce que j'ai dans ma classe Tools
static function
isTrait( $object, $traitName, $autoloader = true )
{
$ret = class_uses( $object, $autoloader ) ;
if( is_array( $ret ) )
{
$ret = array_search( $traitName, $ret ) !== false ;
}
return $ret ;
}
Souvent, vérifier si la partie de l'API que vous avez l'intention d'utiliser est un bon substitut.method_exists ( mixed $object , string $method_name ) : bool
De plus, comme le mentionne @MeatPopsicle, les traits sont souvent utilisés en combinaison avec des interfaces (marqueurs).