IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

accès variable (encapsulation biaisée)


Sujet :

Langage PHP

  1. #1
    Membre actif
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2014
    Messages : 43
    Par défaut accès variable (encapsulation biaisée)
    Salut, il s'agit de mon premier post dans la section PHP,

    Je travaille en ce moment sur un projet perso, bref les détails ne sont pas important, je me suis arrété cependant sur un point qui m'a choqué lors de l'écriture d'une classe.

    Je m'explique, j'écrit le code qui suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
            class A {
                    private $data;
                    public function __get($att) {
                            echo "<p>appel A::__get</p>";
                            return $this->data[$att];
                    }
                    public function __set($att, $val) {
                            echo "<p>appel A::__set</p>";
                            $this->data[$att] = $val;
                    }
                    public function __construct() {
                            echo "<p>const A</p>";
                    }
            }
            class B extends A {
                    public function __construct() {
                            echo "<p>const B</p>";
                            parent::__construct();
                    }
            }
            $a = new A;
            $b = new B;
            $b->var = "ma var";
            echo $b->var;
    ?>
    vous constaterez que ma classe A possède une propriété en private $data à la quelle je peux librement accéder au travers des méthodes magiques __set et __get de la classe B qui en hérite (qui sont elles déclarées en public).
    Je me pose donc des questions sur ce qu'il en est au niveau du respect de l'encapsulation des objets en php...
    Dois-je déclarer les méthodes __get et __set en private et déclarer derrière des méthodes public pour accéder aux propriétés que je souhaite rendre public ?

    Merci

  2. #2
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Salut,

    en fait c'est tout à fait logique : B étends A donc B est une instance implicite de A, vu que les fonctions magiques __get et __set sont déclarées avec une visibilité publique dans A, B au titre de l'héritage y a accès.
    Après ce qui est manipulé par ces 2 fonctions n'est plus du ressort de la classe B (tu n'as pas à te préoccuper de savoir si derrière, l'implémentation de ces fonctions manipule des private ou pas)

    Par contre, B n'a pas d'accès direct à $data , la visibilité private de la classe parente l'en empêche : ce code dans B génère une erreur : $this->data.

    __get et __set sont des fonctions magiques utiles pour manipuler des attributs à la volée sans les déclarer au préalable, les déclarer en private est possible mais inutile, d'ailleurs si tu fais un essai, le moteur de PHP couine.
    Warning: The magic method __get() must have public visibility and cannot be static
    Warning: The magic method __set() must have public visibility and cannot be static
    Dans une architecture soignée, il n'est pas forcément nécessaire d'abuser de ces deux fonctions magiques...

  3. #3
    Membre actif
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2014
    Messages : 43
    Par défaut
    salut merci pour l'interet que tu portes à ma question.

    Je saisis bien le comportement de PHP pour ce code là, mais je trouve que pour le coup l'utilisation de __get ou de __set ruine totalement le principe d'encapsulation de la POO.

    Je me sers des méthodes magiques simplement pour pouvoir utiliser des propriétés à la volé (comme tu l'as bien précisé). Etant donné que ces méthodes doivent être publiques, si ne souhaite pas que l'on ai accès à toutes les valeurs de mes propriétés (contenue dans ma variable $data) je ne peux donc pas utiliser __set ou __get.

    par soucis d'encapsulation j'entends donc ne pas utiliser ces méthodes magiques, mais du coup je me prive de la facilité d'utilisation de ces accesseurs... je trouve que que pour le coup on se retrouve face à un dilemme du a une petite ambiguité de la part du langage, est-ce fais exprès ?, c'est pour le savoir que je cherche l'avis d'un expert.

  4. #4
    Expert confirmé
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Billets dans le blog
    12
    Par défaut
    Si tu laisses une implémentation ouverte des ces fonctions magiques et donc par rapport à la théorie de la POO, je ne peux que te rejoindre : ces fonctions permettent effectivement d'enfreindre le principe d'encapsulation dans la mesure où la responsabilité de la définition/manipulation des valeurs ne relève plus du ressort de la classe implémentant ces fonctions.

    Par contre rien ne t'empêche de reprendre le contrôle dessus en restreignant les possibilités de définition/manipulation : par exemple en vérifiant plus finement ce qui se passe, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    <?php
     
    class Foo
    {
        private $data;
     
        protected $allowed_params = [
            'nom',
            'prenom'
        ];
     
        public function __set($key, $value)
        {
            if (in_array($key, $this->allowed_params, true))
            {
                $this->data = $value;
            }
        }
     
        public function __get($key)
        {
            if (in_array($key, $this->allowed_params, true))
            {
                return  $this->data[$key];
            }
     
            throw new \InvalidArgumentException('Clé inconnue');
        }
    }
     
    class Bar
    extends Foo
    {
        public function __construct()
        {
            // ajout d'un nouveau paramètre
            $this->allowed_params = array_merge($this->allowed_params, ['taille']);
        }
    }
     
    $bar = new Bar();
    $bar->nom = 'abc';
    $bar->prenom = 'def';
     
    echo $bar->age;
     
    ?>
    Pour aller encore plus loin dans le respect de la POO, tu pourrais même surcharger/redéfinir les fonctions magiques dans chaque classe dérivée.

  5. #5
    Membre actif
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2014
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2014
    Messages : 43
    Par défaut
    J'ai un peu de mal avec la logique de PHP je crois...

    Enfait, je trouve dommage de devoir choisir entre respect de la protection des données ou le bénéfice (en pratique) des méthodes magiques, mais je trouve encore plus dommage de devoir se priver de ces méthodes là, alors je vais suivre ton conseil et etre un peu plus spécifique dans les methodes __set et __get.

    thx

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. SSIS 2005 ACCES VARIABLE GLOBALE
    Par mesanges074 dans le forum MS SQL Server
    Réponses: 0
    Dernier message: 02/10/2007, 15h56
  2. Accès Variable globale
    Par viscere dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 31/07/2007, 16h25
  3. [MT] Galère avec thread et mutex pour accès variable
    Par wadcyr8_197 dans le forum Threads & Processus
    Réponses: 36
    Dernier message: 26/07/2007, 15h45
  4. [POO] Accès variables externes
    Par Milts dans le forum Langage
    Réponses: 6
    Dernier message: 20/05/2007, 21h11
  5. [AS2] Problème d'accès variable
    Par wwave dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 19/01/2006, 15h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo