Depuis PHP 5.4.0, PHP supporte une nouvelle manière de rendre le code plus réutilisable : les traits.

Le principe des traits est de permettre de contourner les limites imposées par l'héritage simple de PHP. Le but est de permettre de créer de nouvelles méthodes et de nouvelles propriétés que l'on pourra ajouter à nos différentes classes de manière horizontale.

Fonctionnement de base

Les traits s'écrivent un peu comme une class (attention il n'est cependant pas possible de les instancier)

<?php
trait Rechargeable{

    public $energy = 100;


    public function recharger(){
        $this->energy = 100;
    }

}

Le trait permet de définir des méthodes et des propriétés que l'on va pouvoir réutiliser. On peut ensuite ajouter ce trait aux classes souhaitées

<?php
class Pile extends Battery{

    use Rechargeable;

}

Cela aura pour effet de rajouter les méthodes du trait au sein de la class Pile. Il est possible d'utiliser plusieurs traits.

use Rechargeable, Explosable, Vidable;

Attention aux conflits

Ce système de trait apporte un problème de conflit. En effet que se passe-t-il si 2 traits importés ont des méthodes similaires ?

PHP a prévu le coup et il est possible de définir quel trait utiliser pour certaines méthodes.

class MaClass{

    use A, B {
        B::fonction1 insteadof A;
        A::fonction2 insteadof B;
    }

}

Il est aussi possible d'importer une fonction en la renommant à la volée.

<?php
class MaClass{
    use A, B{
        A::fonction1 insteadof B;
        B::fonction1 as fonction1_A
    }
}

Ceci aura pour effet d'importer la fonction1 du trait A et d'importer la fonction1 du trait B en l'appellant fonction1_A.

Trait de trait

Un trait peut être composé d'autres traits. Le fonctionnement ne diffère pas de ce que l'ont vient de voir.

trait C{
    use A, B;
}

Pour quelle utilisation ?

L'utilisation des traits permet de décomposer le code de nos class en "comportements" et ainsi permettre d'éviter d'avoir des classes contenant des milliers de lignes de codes. Ils permettent aussi de rendre le code réutilisable à travers différentes class qui ont un comportement similaire sans avoir un parent commun.

Mais il faudra quand même prendre en considération quelques inconvénients. Si une classe utilise beaucoup de traits, localiser une méthode peut rapidement devenir un véritable enfer.

Les traits doivent donc être utilisé avec parcimonie pour résoudre des problèmes simples, mais ne doivent pas remplacer l'héritage classique, sous peine de rendre le code plus difficile à lire et à comprendre.