Menu
Coddy logo textTech

Utilisation de plusieurs Traits

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 52 sur 91.

Un seul trait est utile, mais la véritable puissance réside dans la combinaison de plusieurs traits au sein d'une même classe. PHP vous permet d'inclure autant de traits que nécessaire, offrant à votre classe des capacités provenant de plusieurs sources à la fois.

Pour utiliser plusieurs traits, il suffit de les lister en les séparant par des virgules après le mot-clé use :

<?php
trait Timestampable {
    public function getTimestamp(): string {
        return date('Y-m-d H:i:s');
    }
}

trait Identifiable {
    private string $id;
    
    public function generateId(): void {
        $this->id = uniqid('id_');
    }
    
    public function getId(): string {
        return $this->id;
    }
}

class Post {
    use Timestampable, Identifiable;
    
    public function __construct(public string $title) {
        $this->generateId();
    }
}

$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();

Sortie :

id_6789abc123 - 2024-01-15 10:30:00

La classe Post possède désormais des méthodes issues des deux traits. Chaque trait apporte sa propre fonctionnalité : Timestampable fournit des méthodes liées au temps, tandis que Identifiable gère les identifiants uniques. Cette approche permet à chaque trait de rester concentré sur une seule responsabilité, rendant votre code plus modulaire et réutilisable.

Que se passe-t-il lorsque deux traits ont des méthodes portant le même nom ? C'est une situation de conflit que nous explorerons dans la prochaine leçon.

challenge icon

Défi

Facile

Construisons un système de gestion de produits qui combine plusieurs traits pour donner aux produits des capacités de tarification et d'inventaire. Chaque trait gérera une seule responsabilité, et votre classe de produit gagnera des fonctionnalités des deux.

Vous organiserez votre code sur trois fichiers :

  • Priceable.php — Créez un trait appelé Priceable qui gère les fonctionnalités de tarification. Le trait doit avoir :
    • Une propriété privée $price (float)
    • Une méthode setPrice(float $price) qui stocke le prix
    • Une méthode getPrice() qui retourne le prix
    • Une méthode getFormattedPrice() qui retourne le prix formaté comme "$[price]" avec 2 décimales
  • Stockable.php — Créez un trait appelé Stockable qui gère l'inventaire. Le trait doit avoir :
    • Une propriété privée $stock (integer)
    • Une méthode setStock(int $quantity) qui stocke la quantité en stock
    • Une méthode getStock() qui retourne le stock actuel
    • Une méthode isInStock() qui retourne true si le stock est supérieur à 0, false sinon
  • main.php — Incluez les deux fichiers de traits et créez une classe Product qui utilise les deux traits Priceable et Stockable. Utilisez la promotion de constructeur pour définir une propriété publique $name. Le constructeur doit également accepter un prix et une quantité en stock, en utilisant les méthodes des traits pour les définir.

    Vous recevrez trois entrées : un nom de produit, un prix et une quantité en stock. Créez un produit avec ces valeurs et affichez quatre lignes :

    • Le nom du produit
    • Le prix formaté (en utilisant getFormattedPrice())
    • La quantité en stock
    • "Available" si en stock, ou "Out of stock" sinon

Cela démontre comment plusieurs traits fonctionnent ensemble — votre classe Product gagne des capacités de tarification d'un trait et la gestion d'inventaire d'un autre, gardant chaque préoccupation proprement séparée tout en les combinant dans un produit complet.

Aide-mémoire

Pour utiliser plusieurs traits dans une classe, listez-les séparés par des virgules après le mot-clé use :

<?php
trait Timestampable {
    public function getTimestamp(): string {
        return date('Y-m-d H:i:s');
    }
}

trait Identifiable {
    private string $id;
    
    public function generateId(): void {
        $this->id = uniqid('id_');
    }
    
    public function getId(): string {
        return $this->id;
    }
}

class Post {
    use Timestampable, Identifiable;
    
    public function __construct(public string $title) {
        $this->generateId();
    }
}

$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
// Résultat : id_6789abc123 - 2024-01-15 10:30:00

Chaque trait apporte sa propre fonctionnalité à la classe. Cette approche permet à chaque trait de rester concentré sur une seule responsabilité, rendant le code plus modulaire et réutilisable.

Essayez vous-même

<?php
require_once 'Priceable.php';
require_once 'Stockable.php';

// TODO: Créer une classe Product qui utilise les traits Priceable et Stockable
// Utiliser la promotion de constructeur pour la propriété publique $name
// Le constructeur doit accepter name, price, et stock, et utiliser les méthodes des traits pour définir le prix et le stock

class Product {
    // TODO: Utiliser les traits ici

    // TODO: Implémenter le constructeur avec la promotion de constructeur pour $name
    // et définir le prix et le stock en utilisant les méthodes des traits
}

// Lire l'entrée
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));

// TODO: Créer une instance de Product avec les valeurs d'entrée

// TODO: Afficher le nom du produit
// TODO: Afficher le prix formaté en utilisant getFormattedPrice()
// TODO: Afficher la quantité en stock
// TODO: Afficher "Available" si en stock, ou "Out of stock" sinon
?>
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet