Propriétés

En PHP, les variables membres des classes sont aussi appelées propriétés. Ces variables font partie de la définition de la classe et sont utilisées pour représenter l'état d'une instance de cette classe (c.-à-d. à différentier une instance de la classe d'une autre). En pratique, vous désirez souvent gérer la lecture et l'écriture de ces propriété d'une manière particulière. Par exemple, vous pouvez désirer qu'une chaîne de caractères soit toujours nettoyée avant de l'assigner à une propriété label. Vous pouvez utiliser le code suivant pour arriver à cette fin :

$object->label = trim($label);

Le revers du code ci-dessus est que vous devez appeler trim() partout ou vous voulez définir la propriété label. Si, plus tard, la propriété label devient sujette à de nouvelles exigences, telles que la première lettre doit être une capitale, vous auriez à modifier toutes les parties de code qui assignent une valeur à la propriété label. La répétition de code conduit à des bogues, et c'est une pratique courante de l'éviter autant que faire se peut.

Pour résoudre ce problème, Yii introduit une classe de base nommée yii\base\BaseObject qui prend en charge la définition de propriétés sur la base de méthodes d'obtention (getter) et de méthode d'assignation (setters). Si une classe a besoin de cette fonctionnalité, il suffit qu'elle étende la classeyii\base\BaseObject, ou une de ses classes filles.

Info: presque toutes les classes du noyau du framework Yii étendent la classe yii\base\BaseObject ou une de ses classes filles. Cela veut dire, que chaque fois que vous trouvez une méthode d'obtention ou d'assignation dans une classe du noyau, vous pouvez l'utiliser comme une propriété.

Une méthode d'obtention est une méthode dont le nom commence par le mot get (obtenir) et une méthode d'assignation est une méthode dont le nom commence par le mot set (assigner, définir). Le nom après les mots préfixes get ou set définit le nom d'une propriété. Par exemple, une méthode d'obtention getLabel et/ou une méthode d'assignation setLabel obtient et assigne, respectivement, une propriété nommée label, comme le montre le code suivant :

namespace app\components;

use yii\base\BaseObject;

class Foo extends BaseObject
{
    private $_label;

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

    public function setLabel($value)
    {
        $this->_label = trim($value);
    }
}

Pour être tout à fait exact, les méthodes d'obtention et d'assignation créent la propriété label, qui dans ce cas fait référence en interne à une propriété privée nommée _label.

Les propriétés définies par les méthodes d'obtention et d'assignation peuvent être utilisées comme des variables membres de la classe. La différence principale est que, lorsqu'une telle propriété est lue, la méthode d'obtention correspondante est appelée ; lorsqu'une valeur est assignée à la propriété, la méthode d'assignation correspondante est appelée. Par exemple :

// équivalent à $label = $object->getLabel();
$label = $object->label;

// équivalent à $object->setLabel('abc');
$object->label = 'abc';

Une propriété définie par une méthode d'obtention (getter) sans méthode d'assignation (setter) est une propriété en lecture seule. Essayer d'assigner une valeur à une telle propriété provoque une exception InvalidCallException. De façon similaire, une propriété définie par une méthode d'assignation sans méthode d'obtention est en écriture seule. Essayer de lire une telle propriété provoque une exception. Il n'est pas courant d'avoir des propriétés en écriture seule.

Il existe plusieurs règles spéciales pour les propriétés définies via des méthodes d'obtention et d'assignation, ainsi que certaines limitations sur elles.

  • Le nom de telles propriétés sont insensibles à la casse. Par exemple, $object->label et $object->Label sont identiques. Cela est dû au fait que le nom des méthodes dans PHP est insensible à la casse.
  • Si le nom d'une telle propriété est identique à celui d'une variable membre de la classe, le dernier prévaut. Par exemple, si la classe ci-dessus Foo possède une variable momée label, alors l'assignation $object->label = 'abc' affecte la variable membre label ; cette ligne ne fait pas appel à la méthode d'assignation setLabel().
  • Ces propriétés ne prennent pas en charge la visibilité. Cela ne fait aucune différence pour les méthodes d'obtention et d'assignation qui définissent une propriété, que cette propriété soit publique, protégée ou privée.
  • Les propriétés peuvent uniquement être définies par des méthodes d'obtention et d'assignation non-statiques. Les méthodes statiques ne sont pas traitées de la même manière.
  • Un appel normal à la méthode property_exists() ne fonctionne pas pour déterminer des propriétés magiques. Vous devez appeler canGetProperty() ou canSetProperty() respectivement.

En revenant au problème évoqué au début de ce guide, au lieu d'appeler trim() partout où une valeur est assignée à label, vous pouvez vous contenter d'appeler trim() dans la méthode d'assignation setLabel(). Et si une nouvelle exigence apparaît – comme celle de mettre la première lettre en capitale – la méthode setLabel() peut être rapidement modifiée sans avoir à toucher à d'autres parties du code. Cet unique modification affecte l'ensemble des assignation de label.