Maison  >  Article  >  développement back-end  >  Explication graphique et textuelle détaillée de la façon d'appliquer les traits en PHP

Explication graphique et textuelle détaillée de la façon d'appliquer les traits en PHP

伊谢尔伦
伊谢尔伦original
2017-07-03 11:14:311123parcourir

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

Quiconque est familier avec l'orientation objet sait 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.

1. Héritage VS Polymorphisme VS Trait

Il y a maintenant deux classes : Publish.php et Answer.php. Pour y ajouter la fonction LOG, enregistrez les actions à l'intérieur de la classe. Il existe plusieurs options :

Héritage
Polymorphisme
Trait

1.1. Hériter

Comme le montre la figure :

La structure du code est la suivante suit :

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

1.2. Polymorphisme

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, par conséquent, l'implémentation de la journalisation dans les actions Publier et Répondre Même chose. É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.

1.3. Trait

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 voir, nous avons réussi à réutiliser le code sans augmenter la complexité du code.

1.4. Conclusion

Bien que l'héritage puisse également résoudre le problème, son idée va à l'encontre de l'approche orientée objet. Le principe semble très rudimentaire ; la méthode polymorphe est également réalisable, mais elle ne respecte pas le principe DRY en développement logiciel et augmente les coûts de maintenance. La méthode trait évite les défauts ci-dessus et permet une réutilisation du code de manière relativement élégante.

2. Portée du Trait

Après avoir compris les avantages du Trait, nous devons également comprendre les règles de sa mise en œuvre. C'est d'abord la portée. 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();

Le résultat de l'exécution du code ci-dessus est le suivant :
fonction publique
fonction protégée.
fonction privée

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.

3. La priorité de attribut dans le trait

En parlant de priorité, il faut être un objet de référence pour la comparaison. L'objet de référence fait ici référence à la classe du 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 . &#39; public function&#39; . PHP_EOL;
 }
 protected function protectF()
 {
  echo METHOD . &#39; protected function&#39; . PHP_EOL;
 }
}

class Question
{
 public function publicF()
 {
  echo METHOD . &#39; public function&#39; . PHP_EOL;
 }
 protected function protectF()
 {
  echo METHOD . &#39; protected function&#39; . PHP_EOL;
 }
}

class Publish extends Question
{
 use Log;

 public function publicF()
 {
  echo METHOD . &#39; public function&#39; . PHP_EOL;
 }
 public function doPublish()
 {
  $this->publicF();
  $this->protectF();
 }
}
$publish = new Publish();
$publish->doPublish();

La sortie du code ci-dessus est la suivante :
Publish ::publicF public function
Log::protectF protected function

Grâce à l'exemple ci-dessus, les priorités dans les applications Trait peuvent être résumées comme suit :
1. Les membres de la classe actuelle remplacent la méthode du trait
2. Le trait remplace la méthode héritée

La priorité des membres de la classe est : classe actuelle>Trait> >

4. Au lieu de et comme mots-clés


Dans une classe, plusieurs traits peuvent être référencés, comme suit :

Grâce à ce qui précède De cette manière, 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 existe des propriétés ou des méthodes portant le même nom dans deux traits. À ce stade, vous devez utiliser les mots-clés à la place de et as. voir le code d'implémentation suivant :
<?php
trait Log
{
  public function startLog()
  {
    echo METHOD . &#39; public function&#39; . PHP_EOL;
  }
  protected function endLog()
  {
    echo METHOD . &#39; protected function&#39; . 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();
  }
}

Exécutez le code ci-dessus, le résultat de sortie est le suivant :
<?php

trait Log
{
  public function parameterCheck($parameters)
  {
    echo METHOD . &#39; parameter check&#39; . $parameters . PHP_EOL;
  }

  public function startLog()
  {
    echo METHOD . &#39; public function&#39; . PHP_EOL;
  }
}

trait Check
{
  public function parameterCheck($parameters)
  {
    echo METHOD . &#39; parameter check&#39; . $parameters . PHP_EOL;
  }

  public function startLog()
  {
    echo METHOD . &#39; public function&#39; . 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(&#39;params&#39;);
    $this->csl();
  }
}

$publish = new Publish();
$publish->doPublish();


Fonction publique Log::startLogCheck::parameterCheck paramètre checkparamsFonction publique Check::startLog


Tout comme le sens littéral, le mot-clé placeof remplace ce dernier par le premier, et le mot-clé as donne un alias à la méthode remplacée.

utilise le mot-clé use lors de la référence à 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.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn