Résolution des conflits de Traits
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 53 sur 91.
Lorsque deux traits définissent des méthodes portant le même nom, PHP génère une erreur fatale. Vous devez explicitement indiquer à PHP comment gérer ce conflit en utilisant les opérateurs insteadof et as.
<?php
trait FileLogger {
public function log(string $message): void {
echo "File: $message";
}
}
trait DatabaseLogger {
public function log(string $message): void {
echo "DB: $message";
}
}
class Application {
use FileLogger, DatabaseLogger {
FileLogger::log insteadof DatabaseLogger;
DatabaseLogger::log as logToDatabase;
}
}
$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");
Sortie :
File: Error occurred
DB: Error occurredL'opérateur insteadof choisit la méthode de quel trait utiliser lorsqu'il y a un conflit. Dans cet exemple, FileLogger::log l'emporte et devient la méthode log() par défaut. L'opérateur as crée un alias, vous permettant d'accéder à la méthode de l'autre trait sous un nom différent.
Vous pouvez également utiliser as pour modifier la visibilité d'une méthode :
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
Cela rend sayHello() privée au sein de la classe Person, même si elle est publique dans le trait. La résolution de conflits vous donne un contrôle précis sur la manière dont les méthodes de trait s'intègrent dans vos classes.
Défi
FacileConstruisons un système de notification où différents canaux peuvent envoyer des messages, mais nous devons résoudre les conflits lorsque plusieurs traits fournissent le même nom de méthode.
Vous organiserez votre code sur quatre fichiers :
EmailNotifier.php— Créez un trait nomméEmailNotifieravec une méthodenotify(string $message)qui retourne"Email: [message]".SmsNotifier.php— Créez un trait nomméSmsNotifieravec une méthodenotify(string $message)qui retourne"SMS: [message]".AlertService.php— Créez une classeAlertServicequi utilise les deux traits. Comme les deux traits possèdent une méthodenotify(), vous devrez résoudre ce conflit :- Utilisez
EmailNotifier::notifycomme méthodenotify()par défaut - Créez un alias
notifyBySmspour la méthodeSmsNotifier::notify
notifyAll(string $message)qui appelle les deux méthodes de notification et les retourne combinées sur des lignes séparées.- Utilisez
main.php— Incluez tous les fichiers nécessaires et créez une instance deAlertService. Vous recevrez une entrée : une chaîne de caractères pour le message. Affichez trois lignes :- Le résultat de l'appel à
notify()avec le message - Le résultat de l'appel à
notifyBySms()avec le message - Le résultat de l'appel à
notifyAll()avec le message
- Le résultat de l'appel à
Cela démontre comment insteadof résout quelle méthode de trait l'emporte en cas de conflit de nom, tandis que as vous permet de conserver l'accès à la méthode de l'autre trait sous un nom différent.
Aide-mémoire
Lorsque plusieurs traits définissent des méthodes portant le même nom, PHP nécessite une résolution de conflit explicite à l'aide des opérateurs insteadof et as.
L'opérateur insteadof sélectionne la méthode de quel trait utiliser par défaut :
<?php
trait FileLogger {
public function log(string $message): void {
echo "File: $message";
}
}
trait DatabaseLogger {
public function log(string $message): void {
echo "DB: $message";
}
}
class Application {
use FileLogger, DatabaseLogger {
FileLogger::log insteadof DatabaseLogger;
DatabaseLogger::log as logToDatabase;
}
}
$app = new Application();
$app->log("Error occurred"); // File: Error occurred
$app->logToDatabase("Error occurred"); // DB: Error occurred
L'opérateur as crée un alias pour une méthode de trait, permettant d'y accéder sous un nom différent.
Vous pouvez également utiliser as pour modifier la visibilité d'une méthode :
<?php
trait Greeting {
public function sayHello(): void {
echo "Hello!";
}
}
class Person {
use Greeting {
sayHello as private;
}
}
Essayez vous-même
<?php
require_once 'AlertService.php';
// Lire l'entrée
$message = trim(fgets(STDIN));
// TODO : Créer une instance de AlertService
// TODO : Afficher le résultat de l'appel à notify() avec le message
// TODO : Afficher le résultat de l'appel à notifyBySms() avec le message
// TODO : Afficher le résultat de l'appel à notifyAll() avec le message
?>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
1Les bases de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition de méthodeLe mot-clé finalClasses abstraitesRécapitulatif - Hiérarchie des employés7Encapsulation
Public, Protégé, PrivéModificateurs d'accès en détailGetters et SettersMasquage d'informationPromotion de constructeur (8.0)Récapitulatif - Système de gestion d'étudiants10Concepts avancés de la POO
Composition vs HéritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibers (PHP 8.1)Clonage d'objets : analyse approfondieGénérateurs et Itérateurs13Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository2Espaces de noms et Autoloading
Introduction aux espaces de nomsLe mot-clé useStandard d'Autoloading PSR-4L'Autoloader ComposerRécapitulatif - Projet organisé5Interfaces et Contrats
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesInterface vs Classe AbstraiteType Hinting avec les InterfacesRécapitulatif - Calculateur de Formes8Méthodes magiques
Introduction aux méthodes magiques__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Clonage d'objets__serialize & __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d'instance vs Propriétés statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés readonly (PHP 8.1)Récapitulatif - Gestionnaire de compte bancaire6Polymorphisme
Retour sur la redéfinition de méthodePolymorphisme via les interfacesType Hinting et Types d'unionLiaison statique tardiveRécapitulatif - Processeur de paiement9Traits
Introduction aux TraitsUtilisation de plusieurs TraitsRésolution des conflits de TraitsMéthodes abstraites dans les TraitsTraits vs Héritage12Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie