Page 1 sur 1

Quelle methode pour les getter/setter ?

Posté : 11 nov. 2011, 17:20
par untitledoc
Bonjour à tous,

Je me suis mis à l'apprentissage de le POO en PHP. Je suis en train de construire un site et je me demande quel est la meilleur façon d'accéder et de modifier les valeurs des variables de mes classes.

J'ai commencé à écrire une méthode get() et une méthode set() pour chaque variable, mais j'ai une 20aine de variables et je trouve ça un peu répétitif pour faire finalement toujours la même chose. Alors en continuant mes lectures sur le PHP, je vois qu'il est possible d'utiliser des méthodes magiques qui me font la même chose en quelques lignes, quelque soit le nombre de variable.

public function __set($name, $value) {
return $this->$name = $value;
}

public function __get($name) {
return $this->$name;
}

Mais avec cette technique, je ne vois pas trop quel serait la différence si je déclarais toutes les variables en public puisque finalement je vais appeler mes objets comme si j'accédais directement à une variable public. Quel est donc l'intérêt de déclarer tout en private ? et quel est la meilleur façon de créer les getter et setter pour un nombre important de variables?

Merci d'avance :)

Re: Quelle methode pour les getter/setter ?

Posté : 11 nov. 2011, 17:42
par moogli
Salut,

C'est parce que ton exemple est trop simple.

Avec ce type de méthode tu peux définier qu'elles propriétés de la classe tu permet de retourner ou modifier (deux tableaux privatd qui contiennent les propriétés modifiable pour l'un et celle récupérable pour l'autre.

Tu peux aussi imaginé qu'avec la méthode __set() tu filtre et valide les infos qui te sont fournie comme dans un setter que tu ferais par propriété (être certain d'avoir une date, un email etc etc).

Le problème des méthodes magiques c'est que tu peux perdre l'auto complétion et la réflexion sur les méthodes et propriétés concernées.

@+

Re: Quelle methode pour les getter/setter ?

Posté : 20 janv. 2012, 19:20
par devlop78
Tu verras avec le temps d'utilisation POO que les choses ne sont pas aussi simples. D'une part, l'auto complétition, d'autre part, comme tu dis, quel est l'interet d'encapsuler des propriétés pour les lire et écrire depuis l'extérieur sans restriction ? En réalité, sur 20 propriétés déclarées dans une classe, tu n'auras besoin d'en rendre accessible en lecture que 10 et en écriture que 5 (c'est arbitraire mais c'est un exemple tout à fait raisonnable). Et sur les 5, ce sera de TON DEVOIR - que tu peux ne pas remplir si tu veux, ça te regarde - de valider les données qui vont arriver. Un objet, c'est un peu comme un formulaire ... Il ne fait jamais confiance à ce qu'on lui passe. Et s'il enregistre des mauvaises valeurs et qu'il les utilise par la suite, c'est catastrophique ... Et si il doit vérifier à chaque fois qu'il utilise les valeurs si elles sont bonnes ou pas, c'est répétitif et ingérable. Donc, tu as des points d'entrée (qui constitue l'interface de la classe) où tu fais tes controles :
class voiture
{
  protected $_dedans = array()

  public function addPersonne(Animal $personne)
  {
     $this->_dedans[] = $personne;
  }

  public function getPersonnesDedans()
  {
     $personnes = array();
     foreach($this->_dedans as $animal) {
        if ($animal instanceof Humain) {
            $personnes[] = $animal;
        }
     }
     return $personnes;
  }

}
Tu vois dans cet exemple, on n'accede pas depuis l'exterieur à la propriété $_dedans. C'est l'objet qui le gère. De plus, on veut ajouter un élément dans $_dedans, mais la classe vérifie qu'il s'agit bien d'un animal, par exemple pour être sûr plus tard qu'elle pourra lancer $animal->marcheVers($lieu). Par ailleurs, le getteur getPersonnesDedans n'est pas relié à une propriété getPersonnesDedans : en effet, il n'est pas utile que celui qui utilise la classe sache comment elle fonctionne. Il lui faut juste connaitre son rôle, son interface (méthodes accessibles), et c'est à peu près tout. Ainsi, elle instancie une voiture, peut y mettre 2 chiens et 3 humains, récupérer la liste des humains, sans jamais s'inquiéter ni de comment la classe fonctionne, ni de si lorsqu'elle récupère la liste des humains, ce sont bien des humains et non pas des chaines de caractères.

Je déconseille donc l'utilisation générique de __set et __get, qui sont plutot à réserver à des objets conteneurs, qui vont par exemple placer tout dans un tableau pour pouvoir itérer dessus etc ... Comme pour une vue.