web-dev-qa-db-fra.com

Comment vérifier si une classe utilise un trait en PHP?

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?

12
bijiDango

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

10
Mark Baker

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

8
Davi Menezes

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.

5
MeatPopsicle

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

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 ;
}
1
dBags

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).

0