Explication détaillée des propriétés dans Yii

*文
Libérer: 2023-03-18 19:12:01
original
1839 Les gens l'ont consulté

Cet article présente principalement les propriétés (Property) du framework Yii de PHP, et explique en détail les étapes d'implémentation des propriétés. Les amis dans le besoin peuvent s'y référer. J'espère que cela aide tout le monde.

En PHP, les variables membres de la classe sont également appelées propriétés. Ils font partie de la définition de la classe et sont utilisés pour représenter l'état d'une instance (c'est-à-dire pour distinguer les différentes instances de la classe). Dans la pratique spécifique, nous souhaitons souvent utiliser une méthode un peu spéciale pour lire et écrire des attributs. Par exemple, si vous devez effectuer une opération de découpage sur l'attribut label à chaque fois, vous pouvez utiliser le code suivant pour y parvenir :

$object->label = trim($label);
Copier après la connexion

L'inconvénient du code ci-dessus est que tant que l'attribut label est modifié, la fonction trim() doit être rappelée. Si vous devez gérer l'attribut label d'une autre manière à l'avenir, par exemple en mettant la première lettre en majuscule, vous devrez modifier tout le code qui attribue des valeurs à l'attribut label. Cette duplication de code peut conduire à des bugs, et cette pratique doit évidemment être évitée autant que possible.

Pour résoudre ce problème, Yii introduit une classe de base appelée yiibaseObject, qui prend en charge la définition de propriétés basées sur les méthodes getter et setter (lecteur et setter) au sein de la classe. Si une classe doit prendre en charge cette fonctionnalité, elle doit uniquement hériter de yiibaseObject ou de ses sous-classes.

Supplément : presque toutes les classes principales du framework Yii héritent de yiibaseObject ou de ses sous-classes. Cela signifie que chaque fois que vous voyez une méthode getter ou setter dans une classe principale, vous pouvez l'appeler comme une propriété.
Les méthodes Getter sont des méthodes dont les noms commencent par get, tandis que les noms de méthodes setter commencent par set. La partie après get ou set dans le nom de la méthode définit le nom de la propriété. Comme le montre le code suivant, la méthode getter getLabel() et la méthode setter setLabel() opèrent sur l'attribut label :

namespace app\components;

use yii\base\Object;

class Foo extend Object
{
  private $_label;

  public function getLabel()
  {
    return $this->_label;
  }

  public function setLabel($value)
  {
    $this->_label = trim($value);
  }
}
Copier après la connexion

(Explication détaillée : les méthodes getter et setter créent un attribut nommé label, Dans cet exemple, il pointe vers une propriété interne privée _label )

Les propriétés définies par les getters/setters sont utilisées de la même manière que les variables membres de la classe. La principale différence entre les deux est que lorsque cette propriété est lue, la méthode getter correspondante sera appelée et lorsqu'une valeur est attribuée à la propriété, la méthode setter correspondante sera appelée ; Par exemple :

// 等效于 $label = $object->getLabel();
$label = $object->label;

// 等效于 $object->setLabel('abc');
$object->label = 'abc';
Copier après la connexion

Les propriétés qui définissent uniquement des getters et aucun setter sont des propriétés en lecture seule. Toute tentative d'attribution à une telle propriété entraînera une exception yiibaseInvalidCallException (appel invalide). De même, les propriétés définies avec uniquement des méthodes setter mais aucune méthode getter sont des propriétés en écriture seule, et les tentatives de lecture de ces propriétés déclencheront également une exception. Il n'existe pratiquement aucun cas d'utilisation d'attributs en écriture seule.

Les propriétés définies via les getters et les setters ont également des règles et restrictions spéciales :

Les noms de ces propriétés ne sont pas sensibles à la casse. Par exemple, $object->label et $object->Label sont la même propriété. Parce que les noms de méthodes PHP ne sont pas sensibles à la casse.
Si le nom de ce type d'attribut est le même que celui d'une variable membre de la classe, cette dernière prévaudra. Par exemple, supposons que la classe Foo ci-dessus ait une variable membre label, puis l'attribution d'une valeur à $object->label = 'abc' sera attribuée à la variable membre au lieu de la méthode setter setLabel().
Ce type de propriété ne prend pas en charge la visibilité (restrictions d'accès). Le fait que les méthodes getter et setter d'une propriété soient publiques, protégées ou privées n'a aucun effet sur la visibilité de la propriété.
Les méthodes getter et setter de ce type de propriété ne peuvent être définies que comme non statiques. Si elles sont définies comme méthodes statiques (static), elles ne seront pas traitées de la même manière.
Pour en revenir au problème évoqué au début, au lieu d'appeler la fonction trim() partout, il suffit désormais de l'appeler une seule fois dans la méthode setter setLabel(). Si une nouvelle exigence survient selon laquelle la première lettre de l'étiquette doit être en majuscule, il suffit de modifier la méthode setLabel() sans toucher à aucun autre code.

Étapes pour implémenter les attributs

Nous savons que lors de la lecture et de l'écriture d'une variable membre inexistante d'un objet, __get() __set() sera automatiquement appelé. Yii en profite pour prendre en charge les attributs. À partir du code ci-dessus, vous pouvez voir que si vous accédez à une propriété d'un objet, Yii appellera une fonction appelée getpropertyname(). Par exemple, SomeObject->Foo appellera automatiquement SomeObject->getFoo(). Si une propriété est modifiée, la fonction setter correspondante sera appelée. Par exemple, SomeObject->Foo = $someValue appellera automatiquement SomeObject->setFoo($someValue).

Ainsi, pour implémenter les propriétés, il y a généralement trois étapes :

  • Hérite de yiibaseObject .

  • Déclarez une variable membre privée utilisée pour enregistrer cette propriété.

  • Fournit des fonctions getter ou setter, ou les deux, pour accéder et modifier les variables membres privées mentionnées ci-dessus. Si seul le getter est fourni, la propriété est en lecture seule, et si seul le setter est fourni, la propriété est en écriture seule.

La classe Post suivante implémente l'attribut title lisible et inscriptible :

class Post extends yii\base\Object  // 第一步:继承自 yii\base\Object
{
  private $_title;         // 第二步:声明一个私有成员变量

  public function getTitle()    // 第三步:提供getter和setter
  {
    return $this->_title;
  }

  public function setTitle($value)
  {
    $this->_title = trim($value);
  }
}
Copier après la connexion

Théoriquement, le $_title privé est écrit comme $title public, il est également possible de lire et écrire $post->title. Mais ce n’est pas une bonne habitude, et voici pourquoi :

L'encapsulation de la classe est perdue. D'une manière générale, c'est une bonne pratique de programmation de rendre les variables membres invisibles au monde extérieur. Vous ne le verrez peut-être pas d’ici, mais si un jour vous ne souhaitez pas que les utilisateurs modifient le titre, comment le changer ? Comment s'assurer que le titre n'est pas modifié directement dans le code ? Si un setter est fourni, tant que le setter est supprimé, une exception sera levée s'il y a des écritures non nettoyées dans l'en-tête. Si vous utilisez la méthode public $title, vous pouvez vérifier les exceptions d'écriture en la remplaçant par private $title, mais la lecture est également interdite.
Pour l'écriture du titre, vous souhaitez supprimer les espaces. En utilisant la méthode setter, il vous suffit d'appeler trim() à cet endroit comme l'extrait de code ci-dessus. Mais si vous utilisez la méthode public $title, il ne fait aucun doute que trim() sera appelé à chaque instruction d'écriture. Pouvez-vous garantir que rien ne manque ?
Par conséquent, utiliser public $title n'est que rapide et semble simple, mais les modifications futures seront gênantes. On peut dire que c'est un cauchemar. C’est le sens du génie logiciel, rendre le code facile à maintenir et à modifier grâce à certaines méthodes. Cela peut sembler inutile au début, mais en fait, les amis qui ont subi des pertes ou qui ont été forcés par le patron du client de modifier le code écrit par le programmeur précédent et qui ont salué ses proches penseront tous que cela est très nécessaire.

Cependant, il n’y a pas d’absolu dans ce monde. Étant donné que __get() et __set() traversent toutes les variables membres, elles ne sont appelées que lorsqu'aucune variable membre correspondante n'est trouvée. Par conséquent, son efficacité est intrinsèquement inférieure à celle de l’utilisation de variables membres. Dans certaines situations simples où les structures de données, les collections de données, etc. sont représentées et où le contrôle en lecture-écriture n'est pas requis, vous pouvez envisager d'utiliser des variables membres comme attributs, ce qui peut améliorer l'efficacité.

Une autre petite astuce pour améliorer l'efficacité est la suivante : utilisez $pro = $object->getPro() au lieu de $pro = $object->pro et utilisez $objcect->setPro($value) à la place. de $object->pro = $value. Cela a exactement le même effet fonctionnel, mais évite l'utilisation de __get() et __set(), ce qui équivaut à contourner le processus de traversée.

Je pense que quelqu'un devrait me gronder ici. Yii a finalement implémenté le mécanisme d'attribut juste pour la commodité des développeurs. Cependant, je suis ici pour vous apprendre à utiliser la méthode originale pour améliorer la soi-disant efficacité. En effet, il existe une certaine contradiction entre la commodité du développement et la grande efficacité de l'exécution. Mon point de vue personnel est plus enclin à donner la priorité à la commodité et à faire bon usage des conditions pratiques que Yii crée pour nous. Quant à l'efficacité, le framework lui-même doit y prêter plus d'attention tant que nous n'écrivons pas de code supplémentaire, tout ira bien.

Mais vous pouvez être assuré que dans le framework Yii, un code comme $app->request apparaît rarement, à la place $app->getRequest() est utilisé. En d’autres termes, le framework lui-même accorde une attention particulière à l’efficacité et la commodité est laissée aux développeurs. Bref, voici juste un point de connaissance. Quant à savoir s'il faut l'utiliser et comment l'utiliser, cela dépend entièrement de vous.

Il convient de noter :

Parce que le moment de l'appel automatique de __get() __set() ne se produit que lors de l'accès à des variables membres inexistantes. Par conséquent, si la variable membre public $title est définie, alors même si getTitle() setTitle() est définie, elle ne sera pas appelée. Parce que $post->title pointera directement vers le public $title, __get() __set() ne sera pas appelé. Il a été coupé de la racine.
Puisque PHP n'est pas sensible à la casse pour les méthodes de classe, $post->getTitle() et $post->gettitle() appellent la même fonction. Par conséquent, $post->title et $post->Title sont la même propriété. Autrement dit, les noms d'attributs ne sont pas non plus sensibles à la casse.
Puisque __get() __set() sont tous deux publics, cela n'a aucun sens que getTitle() setTitle() soit déclaré public, privé ou protégé. Il est également accessible de l'extérieur. Toutes les propriétés sont donc publiques.
Puisque __get() et __set() ne sont pas statiques, il n'y a aucun moyen d'utiliser des attributs statiques.
Autres méthodes d'Object liées aux attributs

En plus de __get() __set(), yiibaseObject fournit également les méthodes suivantes pour faciliter l'utilisation des attributs :

  • __isset() est utilisé pour tester si la valeur de la propriété n'est pas nulle et est automatiquement appelé lorsque isset($object->property). Notez que cette propriété doit avoir un getter correspondant.

  • __unset() est utilisé pour définir la valeur de la propriété sur null et est automatiquement appelé lorsqu'il n'est pas défini($object->property). Notez que cette propriété doit avoir un setter correspondant.

  • hasProperty() est utilisé pour tester s'il existe une certaine propriété. Autrement dit, un getter ou un setter est défini. Si le paramètre $checkVars = true de hasProperty() (la valeur par défaut est true), alors toute variable membre portant le même nom est également considérée comme ayant cette propriété, comme le $title public mentionné précédemment.

  • canGetProperty() teste si une propriété est lisible. La signification du paramètre $checkVars est la même que ci-dessus. Tant que le getter est défini, la propriété est lisible. De plus, si $checkVars est true . Ensuite, tant que la classe définit des variables membres, qu'elles soient publiques, privées ou protégées, elles sont considérées comme lisibles.

  • canSetProperty() teste si une propriété est accessible en écriture. La signification du paramètre $checkVars est la même que ci-dessus. Tant que le setter est défini, la propriété peut être écrite. En même temps, $checkVars est true . Ensuite, tant que la classe définit des variables membres, qu'elles soient publiques, privées ou protégées, elles sont considérées comme accessibles en écriture.

  • Objet et composant

yiibaseComponent hérite de yiibaseObject, il possède donc également des fonctions de base telles que des propriétés.

Cependant, puisque Component introduit également des événements et des comportements, il n'hérite pas simplement de la méthode d'implémentation des propriétés d'Object, mais surcharge des fonctions telles que __get() __set() basées sur le même mécanisme. Mais en termes de mécanisme de mise en œuvre, ce sont les mêmes. Cela n’affecte pas la compréhension.

Comme mentionné précédemment, Yii se positionne officiellement comme un framework basé sur des composants. Le concept de composants visibles est le fondement de Yii. Si vous souhaitez lire le code source ou la documentation de l'API de Yii, vous constaterez que presque toutes les classes principales de Yii sont dérivées (héritées de) yiibaseComponent.

Dans Yii1.1, il y avait déjà un composant, qui était à cette époque CComponent. Yii2 divise CComponent dans Yii1.1 en deux classes : yiibaseObject et yiibaseComponent.

Parmi eux, Object est relativement léger et définit les propriétés de la classe via des getters et des setters. Le composant est dérivé d'Object et prend en charge les événements et les comportements. Par conséquent, la classe Component a trois caractéristiques importantes :

  • propriété

  • événement

  • Comportement

Je crois que vous avez plus ou moins compris que ces trois fonctionnalités sont des points d'entrée importants pour enrichir et étendre les fonctions de classe et changer les comportements de classe. Par conséquent, Component a un statut très élevé dans Yii.

Tout en offrant plus de fonctions et de commodité, Component a ajouté les deux fonctionnalités d'événement et de comportement, ce qui facilite le développement tout en sacrifiant une certaine efficacité. Si vous n'avez pas besoin d'utiliser les deux fonctionnalités d'événement et de comportement pendant le développement, comme une classe qui représente certaines données. Ensuite, vous ne pouvez pas hériter du composant, mais hériter de l'objet. Un scénario d'application typique consiste à utiliser Object s'il représente un ensemble de données saisies par l'utilisateur. Et si vous avez besoin de traiter le comportement de l'objet et les événements qui peuvent répondre au traitement, il ne fait aucun doute que Component doit être utilisé. En termes d'efficacité, Object est plus proche des classes PHP natives. Par conséquent, Object doit être utilisé en premier lorsque cela est possible.

Recommandations associées :

Explication détaillée du mécanisme de fonctionnement et du routage de Yii

Comment Yii cache index.php dans l'URL

Résumé des opérations de requête de base de données du framework PHP Yii

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!