0
Posted by alex on Aug 22nd, 2008

elephpant-elephant-php-logoPour ceux d'entre vous qui font du PHP le moindrement sérieusement, vous avez sans doute remarqué que PHP manque quelque chose du coté de la POO.

C, Visual Basic, C#, et plusieurs autres langages ont la capacité d'avoir des variables publiques en lecture seule dans une classe. C'est à dire que la variable peut être modifié à l'intérieur de la classe, mais à l'extérieur on ne peut que la lire !
Prenons l'exemple suivant:

J'ai une classe qui s'appelle utilisateur et qui gère une session utilisateur:

Class utilisateur {

[....]

public $id = 0;

public $nom = '';

[....]

}

Admettons que les valeurs de $nom et $id proviennent d'une base de données, il serait fort probablement utile de pouvoir y accéder depuis l'extérieur de la classe! Bref j'aimerais pouvoir lire $nom et $id mais je ne veux pas qu'elles puissent être modifier à l'extérieur de la classe (cela pourrait causer des erreurs, des problèmes de sécurité, des problèmes de conception, etc).

Par exemple:

echo "Je suis  {$utilisateur->nom} et mon id est {$utilisateur->id}";

Mais en les mettant publique, il y a un problème, on peut aussi les modifier depuis l'extérieur de la classe. Parfois cela est voulu, mais souvent cela pourrait provoquer des erreurs.

$utilisateur->nom = 'robert';

echo "Je suis  {$utilisateur->nom} et mon id est {$utilisateur->id}";

Une solution à ce problème serait l'utilisation de getters, mais cela est très peu pratique si nous avons beaucoup de variables.

Par exemple:

Class utilisateur {

[....]

private $id = 0;

private $nom = '';

public function getNom(){

return $this->nom;

}

public function getId(){

return $this->id;

}

[....]

}

echo 'Je suis  '.$utilisateur->nom().' et mon id est '.$utilisateur->id();

À force de me creuser les méninges, j'en suis venu à une idée basée sur l'utilisation des méthodes magiques. (Pour ceux qui ne connaisse pas, les fonctions __get et __set sont appelées lorsqu'aucune variable publique ne correspond à celle demandé). Une petite astuce permet d'avoir des variables en readonly sans avoir recours à un getter pour chaque variable!

exemple:

Class utilisateur {

[....]

private $id = 0;

private $nom = '';

public function __get($name){

return $this->$name;

}

[....]

}

echo "Je suis  {$utilisateur->nom} et mon id est {$utilisateur->id}";

$toto->nom = 'robert'; // Va retourner une erreur :)

Et voilà, c'est magique ! Il reste un inconvénient (mais qui est facilement contournable) : On ne veut pas forcément donner accès à toutes nos variables privée publiquement, même si ce n'est qu'en lecture ! Il y a plusieurs façons de contourner ça, par exemple précéder toutes ses variables publiques+readonly par un underscore:

public function __get($name){

if ($name[0] === '_') return $this->$name;

}

Ou encore utiliser un array de variable readonly (mais ce n'est pas forcément performant...):

public function __get($name){

$readonly = array('id','nom');

if (in_array($name,$readonly)) return $this->$name;

}

Les exemples dans cet article devrait être complété avec des vérifications d'erreurs, des isset et l'appel à quelques autres méthodes magiques, mais dans un soucis de simplicité je n'expliquerai pas tout dans cet article :P

Enfin bref, vous comprennez le principe, à vous de vous amusez :)

Bonne prog !

0 comment
Connectez-vous ou postez en tant qu'invité:
Your Name Your Email


Vérification: 0475
Go to Top