À partir de la version 5.4.0 de PHP, PHP propose un nouveau concept de réutilisation de code, qui est Trait. Trait signifie littéralement « caractéristiques » et « fonctionnalités ». On peut comprendre que l'utilisation du mot-clé Trait peut ajouter de nouvelles caractéristiques aux classes en PHP.
Tous ceux qui sont familiers avec l'orientation objet savent qu'il existe deux méthodes de réutilisation de code couramment utilisées dans le développement logiciel : l'héritage et le polymorphisme. En PHP, un seul héritage peut être obtenu. Les traits évitent cela. Ce qui suit est une explication comparative à travers un exemple simple.
Maintenant, il existe des types
Publish.php
et
Answer.php
. Pour y ajouter la fonction LOG, enregistrez les actions à l'intérieur de la classe. Il existe plusieurs solutions :
Héritage
Polymorphisme
Trait
comme l'Image. :
La structure du code est la suivante :
// Log.php <?php Class Log { public function startLog() { // echo ... } public function endLog() { // echo ... } } // Publish.php <?php Class Publish extends Log { } // Answer.php <?php Class Answer extends Log { }
Vous pouvez voir que l'héritage répond aux exigences. Mais cela viole le principe orienté objet. La relation entre les opérations telles que Publier, Répondre et Journaliser n'est pas la relation entre la sous-classe et la classe parent. Il n’est donc pas recommandé de l’utiliser de cette façon.
Comme indiqué :
Code d'implémentation :
// Log.php <?php Interface Log { public function startLog(); public function endLog(); } // Publish.php <?php Class Publish implements Log { public function startLog() { // TODO: Implement startLog() method. } public function endLog() { // TODO: Implement endLog() method. } } // Answer.php <?php Class Answer implements Log { public function startLog() { // TODO: Implement startLog() method. } public function endLog() { // TODO: Implement endLog() method. } }
Les opérations de journalisation doivent être les mêmes, donc l'implémentation de la journalisation dans les actions Publier et Répondre est également la même. Évidemment, cela viole le principe DRY (Don’t Repeat Yourself). Il n’est donc pas recommandé de le mettre en œuvre de cette façon.
comme indiqué :
Le code d'implémentation est le suivant :
// Log.php <?php trait Log{ public function startLog() { // echo .. } public function endLog() { // echo .. } } // Publish.php <?php class Publish { use Log; } $publish = new Publish(); $publish->startLog(); $publish->endLog(); // Answer.php <?php class Answer { use Log; } $answer = new Answer(); $answer->startLog(); $answer->endLog();
Comme vous pouvez le constater, nous avons réussi à réutiliser le code sans augmenter la complexité du code.
Bien que la méthode d'héritage puisse également résoudre le problème, son idée viole le principe orienté objet et semble très grossière, le polymorphisme est également réalisable ; , il ne respecte pas le principe DRY dans le développement de logiciels et augmente les coûts de maintenance. La méthode des traits évite les défauts ci-dessus et permet une réutilisation du code de manière relativement élégante.
Après avoir compris les avantages du Trait, nous devons également comprendre les règles de sa mise en œuvre. C'est plus facile à prouver. Le code d'implémentation est le suivant :
<?php class Publish { use Log; public function doPublish() { $this->publicF(); $this->protectF(); $this->privateF(); } } $publish = new Publish(); $publish->doPublish(); 执行上述代码输出结果如下: public function protected function private function
On peut constater que la portée de Trait est visible à l'intérieur de la classe Trait qui y fait référence. On peut comprendre que le mot-clé use copie le code d'implémentation du Trait dans la classe qui référence le Trait.
En ce qui concerne la priorité, il doit y avoir un objet de référence pour la comparaison. L'objet de référence ici est la classe qui fait référence au. Trait. et sa classe parent.
Utilisez le code suivant pour prouver la priorité des attributs dans l'application Trait :
<?php trait Log { public function publicF() { echo __METHOD__ . ' public function' . PHP_EOL; } protected function protectF() { echo __METHOD__ . ' protected function' . PHP_EOL; } } class Question { public function publicF() { echo __METHOD__ . ' public function' . PHP_EOL; } protected function protectF() { echo __METHOD__ . ' protected function' . PHP_EOL; } } class Publish extends Question { use Log; public function publicF() { echo __METHOD__ . ' public function' . PHP_EOL; } public function doPublish() { $this->publicF(); $this->protectF(); } } $publish = new Publish(); $publish->doPublish(); 上述代码的输出结果如下: Publish::publicF public function Log::protectF protected function
Grâce à l'exemple ci-dessus, vous pouvez résumer la priorité dans l'application Trait comme suit :
Les membres de la classe actuelle remplacent les méthodes de trait
le trait remplace les méthodes héritées
La priorité des membres de la classe est :
当前类>Trait>父类
peuvent référencer plusieurs Traits dans une classe, comme suit :
<?php trait Log { public function startLog() { echo __METHOD__ . ' public function' . PHP_EOL; } protected function endLog() { echo __METHOD__ . ' protected function' . PHP_EOL; } } trait Check { public function parameterCheck($parameters) { // do sth } } class Publish extends Question { use Log,Check; public function doPublish($para) { $this->startLog(); $this->parameterCheck($para); $this->endLog(); } }
À travers le méthode ci-dessus, nous pouvons référencer plusieurs traits dans une classe. Lors du référencement de plusieurs Traits, il est facile de causer des problèmes. Le problème le plus courant est que faire s'il y a des propriétés ou des méthodes portant le même nom dans deux Traits. Dans ce cas, vous devez utiliser
Insteadof
as
<?php trait Log { public function parameterCheck($parameters) { echo __METHOD__ . ' parameter check' . $parameters . PHP_EOL; } public function startLog() { echo __METHOD__ . ' public function' . PHP_EOL; } } trait Check { public function parameterCheck($parameters) { echo __METHOD__ . ' parameter check' . $parameters . PHP_EOL; } public function startLog() { echo __METHOD__ . ' public function' . PHP_EOL; } } class Publish { use Check, Log { Check::parameterCheck insteadof Log; Log::startLog insteadof Check; Check::startLog as csl; } public function doPublish() { $this->startLog(); $this->parameterCheck('params'); $this->csl(); } } $publish = new Publish(); $publish->doPublish();
Log::startLog public function Check::parameterCheck parameter checkparams Check::startLog public function
insteadof
as
Lors du référencement à Trait, le mot-clé use est également utilisé pour faire référence à l'espace de noms. La différence entre les deux est que lors de la référence à Trait, il est utilisé à l'intérieur de la classe.