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 :

[POO] Public ou Protected


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut [POO] Public ou Protected
    Bonjour à tous et à toutes ^^

    je suis en train de développer un petit Framework pour améliorer mes connaissances dans l'utilisation de la POO en PHP.

    Je me trouve face à une interrogation sur la visibilité de certaines propriétés de mon objet.

    Disons que j'ai une table "Articles" avec comme champs ID - TITRE - MESSAGE.

    Lors de l'implémentation vous me conseillez quoi comme : ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Class Articles{
        protected
             $titre,
             $message;
     
         // + ASSESSEUR ET MUTATEUR. 
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Class Articles{
        // Propriété propres à la tables définies à la volée dans un tableau en protected.
        protected
          $var = array();
     
         public function get_var($key){
            return $this->var[$key];
         }
     
         public function set_var($key, $value){
            $this->var[$key] = $value;
         }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Class Articles{
        // Propriété propres à la tables définies à la volée et donc en public.
    }
    L'avantage des deux dernières façon est de rendre le code plus générale ... si des modifications au lieu dans la table, pas besoin de modifier les propriétés de la classe.

    La question principale concerne principalement les deux dernières façon car la 1er revient au même que la 2eme mais en mieux.

    Qu'en pensez vous ?

    merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    D'expérience, j'opterai pour la deuxième méthode mais en la complétant.
    Je définirai un tableau de mot-clés acceptés par la fonction set_var().
    Ensuite en commentaire des fonctions tu mets la liste des mots-clés disponibles.
    Les systèmes très rigides avec des accesseurs et mutateurs pour chaque attribut ne tiennent pas longtemps quand il s'agit de manipuler des données aussi volatiles. Cela alourdit sévèrement toute modification ultérieure.

    Réserve les set et get que pour les classes de base de ton framework (les fondations) et privilégie la paire (mot-clé, valeur) pour tout le reste.
    Cette approche t'oblige à vérifier les mots-clés et à bien commenter toutes tes fonctions pour t'y retrouver mais quelle souplesse en contrepartie.
    En plus, pour ne rien gâcher, tu peux très bien factoriser le code traitant cette partie dans une classe abstraite qui ne gère que ça et du coup tu pourras rendre privé ton tableau de valeurs.

  3. #3
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Une autre façon d'utiliser la deuxième forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Article extends ArrayObject {
     
      public function __construct () {
        parent::__construct(array(), ArrayObject::ARRAY_AS_PROPS);
      }
     
    }
     
    $article = new Article;
    $article->test = "Hello";
     
    var_dump($article->test);
    Et ainsi, tout le boulot sur les attributs est fait par ArrayObject

    Je te rappelle également que les accesseurs (getters/setters) peuvent prendre la forme de méthodes magiques __get et __set qui permettent d'utiliser naturellement des indexs d'un tableau associatif (propriété de la classe) de la même façon que s'il s'agissait de propriétés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Article {
       protected $_data;
       public function __construct () { $this->_data = array(); }
       public function __get ($key) { return isset($this->_data[$key]) ? $this->_data[$key] : null; }
       public function __set ($key, $value) { $this->_data[$key] = $value; }
    }
     
    $article = new Article;
    $article->test = "Hello";
     
    var_dump($article->test);
    }
    Sinon, pour mes classes Modèles (typiquement Article est une classe du modèle), j'utilise cette classe:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    <?php
    /**
     * Axiom: a lightweight PHP framework
     *
     * @copyright Copyright 2010-2011, Benjamin Delespierre (http://bdelespierre.fr)
     * @licence http://www.gnu.org/licenses/lgpl.html Lesser General Public Licence version 3
     */
     
    /**
     * Model Base Class
     *
     * @abstract
     * @author Delespierre
     * @package core
     * @subpackage Model
     */
    abstract class Model {
     
        /**
         * Model key id
         * @var string
         */
        protected $_id_key = 'id';
     
        /**
         * Model's data
         * @var array
         */
        protected $_data = array();
     
        /**
         * Statements cache
         * @var array
         */
        protected $_statements = array();
     
        /**
         * Initialize a model statement (part of CRUD)
         * @abstract
         * @param string $statement
         * @return PDOStatement
         */
        abstract protected function _init ($statement);
     
        /**
         * Default constructor
         * @param mixed $id
         * @throws RuntimeException
         */
        public function __construct ($id = null) {
            if ($id !== null && $id !== false && !$this->find($id))
                throw new RuntimeException("Cannot instanciate model", 2009);
        }
     
        /**
         * __sleep overloading
         * @return array
         */
        public function __sleep () {
            return array('_id_key', '_data');
        }
     
        /**
         * Getter
         * @param string $key
         * @return mixed
         */
        public function __get ($key) {
            return isset($this->_data[$key]) ? $this->_data[$key] : null;
        }
     
        /**
         * Setter
         * @param string $key
         * @param mixed $value
         * @return void
         */
        public function __set ($key, $value) {
            $this->_data[$key] = $value;
        }
     
        /**
         * __isset overloading
         * @param string $key
         * @return boolean
         */
        public function __isset ($key) {
            return isset($this->_data[$key]);
        }
     
        /**
         * Get internal data
         * @internal
         * @return array
         */
        public function getData () {
            return $this->_data;
        }
     
        /**
         * Retrieve method
         * Will return false in case of error
         * @param mixed $id
         * @return Model
         */
        public function find ($id) {
            if (!$this->_init("retrieve"))
                throw new RuntimeException("Cannot initialize " . __METHOD__, 2010);
     
            if ($this->_statements['retrieve']->execute(array(":{$this->_id_key}" => $id))) {
                if ($this->_statements['retrieve']->rowCount()) {
                    $this->_data = $this->_statements['retrieve']->fetch(PDO::FETCH_ASSOC);
                    return $this;
                }
            }
            return false;
        }
     
        /**
         * Create methode
         * Will return false in case of error
         * @param array $data
         * @throws RuntimeException
         * @return Model
         */
        public function create ($data) {
            if (!$this->_init("create"))
                throw new RuntimeException("Cannot initialize " . __METHOD__, 2011);
     
            if ($this->_statements['create']->execute(array_keys_prefix($data, ':'))) {
                $id = Database::lastInsertId();
                return $this->find($id);
            }
            return false;
        }
     
        /**
         * Update method
         * @throws RuntimeException
         * @return boolean
         */
        public function update ($data = array()) {
            if (!$this->_init("update"))
                throw new RuntimeException("Cannot initialize " . __METHOD__, 2012);
     
            if (!empty($this->_data)) {
                $inputs = array_merge($this->_data, array_intersect_key($data, $this->_data));
                return $this->_statements['update']->execute(array_keys_prefix($inputs, ':'));
            }
            return false;
        }
     
        /**
         * Delete method
         * @throws RuntimeException
         * @return boolean
         */
        public function delete () {
            if (!$this->_init("delete"))
                throw new RuntimeException("Cannot initialize " . __METHOD__, 2013);
     
            if (!empty($this->_data))
                return $this->_statements['delete']->execute(array(":{$this->_id_key}" => $this->_data[$this->_id_key]));
            return false;
        }
    }
    Note: il faut virer toutes les références à array_key_prefix, c'est complêtement inutile...

    Note: Database est une façade statique de PDO.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Bonjour,

    merci pour la réponse rapide, ca confirme ma pensée

    Je définirai un tableau de mot-clés acceptés par la fonction set_var()
    Tu veux dire par la un, un "truc" du genre ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    protected 
    $var_authorized = array('titre', 'message' ....);
     
    Qui ferai le tri dans les variables envoyés à la fonction set_var ?

    En plus, pour ne rien gâcher, tu peux très bien factoriser le code traitant cette partie dans une classe abstraite qui ne gère que ça et du coup tu pourras rendre privé ton tableau de valeurs.
    Oui c'est vers ca que je veux aller

    EDIT : Oupss, je n'avais pas vu la 2eme réponse ^^

    Je ne connaissais pas ArrayObject, je vais regarder de plus prés.

    Sinon normalement ma classe Article extend ma classe ModelCore, qui fait ce que t'a classe model fait mais en bcp moins générale ^^

    Concernant ce code ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Article {
       protected $_data;
       public function __construct () { $this->_data = array(); }
       public function __get ($key) { return isset($this->_data[$key]) ? $this->_data[$key] : null; }
       public function __set ($key, $value) { $this->_data[$key] = $value; }
    }
     
    $article = new Article;
    $article->test = "Hello";
     
    var_dump($article->test);
    }
    Sympa comme façon de faire, je n'y aurai pas penser :p

    Avec un in_array sur le tableau de mot clé (comme expliqué par rawsrc), ca permet de n'avoir dedans que des données connues.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Désolé pour le double post ^^

    Je repense à votre méthode avec les get et set magique ^^

    Comment l'utiliseriez vous sur un model avec des données multilingue ?

    Vous créeriez un deuxième tableau comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $var_trad = array ('fr' => array ('name' => 'test'));
    Ou vous partiriez sur une autre facon de faire ?

    EDIT : j'ai implémenté les set et get magique comme 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class ModelCore{
     
        protected
        /** @var integer Identifiant */
        $id,
        /** @var array Tableau contenant les données de la table */
        $var = array(),
        /** @var array Tableau contenant les données de la table */
        $var_tf = array(),
        /** @var array Tableau contenant les mots clés autorisés */
        $var_authorized = array(),
        /** @var array Tableau contenant les mots clés pour le mul */
        $var_tf_authorized = array(),
        /** @var boolean True si l'objet est chargé correctement */
        $loaded = false,
        /** @var array Tableau d'erreurs */
        $error;
     
        public function __get($key) {
            if (in_array($key, $this->var_authorized)) {
                return (isset($this->var[$key])) ? $this->var[$key] : '';
            } elseif (in_array($key, $this->var_tf_authorized)) {
                if (isset($this->var_tf[$GLOBALS['currentLang']][$key]))
                    return $this->var_tf[$GLOBALS['currentLang']][$key];
                elseif (isset($this->var_tf[_DEFAULT_LANG][$key]))
                    return $this->var_tf[_DEFAULT_LANG][$key];
            }
     
            return null;
        }
     
        public function __set($key, $value) {
            if (in_array($key, $this->var_authorized)) {
                $this->var[$key] = $value;
            } elseif (in_array($key, $this->var_tf_authorized)) {
                $this->var_tf[$GLOBALS['currentLang']][$key] = $value;
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Articles extends ModelCore {
     
        protected
        $var_authorized = array('price'),
        $var_tf_authorized = array('name');
    }
    Utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $GLOBALS['currentLang'] = "fr";
     
    $a = new Articles();
     
    $a->description = "testetstest";
    $a->price = 10;
    $a->name = "test";
    Résultat :
    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
     
    object(Articles)[1]
      protected 'var_authorized' => 
        array
          0 => string 'price' (length=5)
      protected 'var_tf_authorized' => 
        array
          0 => string 'name' (length=4)
      protected 'id' => null
      protected 'var' => 
        array
          'price' => int 10
      protected 'var_tf' => 
        array
          'fr' => 
            array
              'name' => string 'test' (length=4)
      protected 'loaded' => boolean false
      protected 'error' => null
    Que pensez vous des modifications effectué ?

    Merci pour l'aide apporté

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je pense personnellement que l'internationalisation n'a rien à voir avec le modèle à moins que ce dernier ne soit lui-même multilingue.

    Ou vous partiriez sur une autre facon de faire ?
    Personnellement, j'ai des tables de traductions sur des fichiers ini et une classe capable de faire la transition et de détecter les langues selon le navigateur.

    Tu peux regarder la classe Lang d'Axiom pour avoir des idées (voir ma signature).

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Par modèle, tu parle bien de ma classe article dans ce cas ci ?

    En base de données, il est structuré comme suit (simplifié) :
    [Articles] --> id
    [Articles_lang] -> language_fk, articles_fk, content


    EDIT : Je vais aller y jeter un coup d'oeil ^^

    Petite question : pourquoi utilise tu des fichiers .ini pour les lang ?

    Pour ma part, pour les traductions "non dynamique", je pensais partir sur des tableaux de lang stocké dans la superglobale $GLOBALS. C'est une mauvaise idée selon toi ?

  8. #8
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Petite question : pourquoi utilise tu des fichiers .ini pour les lang ?
    Parce que c'est simple et que ça couvre 99% de mes besoins

    Pour ma part, pour les traductions "non dynamique", je pensais partir sur des tableaux de lang stocké dans la superglobale $GLOBALS. C'est une mauvaise idée selon toi ?
    Y'a pas 36 façons de faire du g11n et de l'i18n: soit tu sors la machine de guerre qui s'appelle gettext, très complexe à mettre en place, non supporté par pleins d'hébergeurs etc. Soit tu fais un moteur à ta sauce qui réponds à ton besoin. Le fait de tout mettre sur des fichiers ini ne change rien par rapport à l'utilisation des globals sauf que: ça ne pourrit pas le namespace global et tu peux donner un fichier plain/text éditable par ton client.

    Le moteur que j'ai fait permet tout bêtement de remplacer du texte dans les traductions.

    Exemple:
    fichier en.ini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [translations]
    foo.bar = "Say hello to %s"
    fichier fr.ini
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [translations]
    foo.bar = "Dites bonjour à %s"
    usage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <p>bla bla bla <?=i18n('foo.bar', 'peter')?>
    On peut difficilement faire plus simple :p

    Pour ce qui est du multilinguisme au niveau du modèle (Article est un bon exemple), je gère plusieurs couples title/body par Article dans des tables MyISAM avec des clés fulltext pour la recherche. Donc un même article peut être rédigé en plusieurs langues et une méthode de la classe Article permet de choisir laquelle afficher.

  9. #9
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    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
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    Je pense personnellement que l'internationalisation n'a rien à voir avec le modèle à moins que ce dernier ne soit lui-même multilingue.
    Tout à fait, il ne faut pas vouloir courir plusieurs chevaux à la fois.
    Généralement tout mélanger dans une super classe pour économiser je ne sais quoi est une très mauvaise idée et se termine souvent dans une impasse.

    Voici le code en accord avec mon message :
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    <?php
     
    abstract class Dto {
     
       /**
        * Tableau des clés autorisées
        * @var array Array([] => key)
        */
       private $keys = array();
     
       /**
        * Tableau des données
        * @var array Arra(key => value)
        */
       private $data = array();
     
       /**
        * Tableau des clés autorisées
        * @param array $keys Array([] => key)
        */
       function __construct(array $keys) {
          $this->keys = $keys;
       }
     
       /**
        * @param mixed $key
        * @param mixed $value
        * @return bool
        */
       function set($key, $value) {
          if (in_array($key, $this->keys)) {
             $this->data[$key] = $value;
             return TRUE;
          }
          return FALSE;
       }
     
       /**
        * @param string $key
        * @return mixed|NULL
        */
       function get($key) {
          return $this->data[$key];
       }
     
       /**
        * @param mixed $key
        * @param mixed $value
        * @return bool
        */
       function __set($key, $value) {
          return $this->set($key, $value);
       }
     
       /**
        * @param string $key
        * @return mixed|NULL
        */
       function __get($key) {
          return $this->get($key);
       }
     
       /**
        * @return array Array(key => value)
        */
       function getAll() {
          return $this->data;
       }
    }
     
     
    /**
     * @method bool set($key, $value) $key = { id, titre, message }
     * @method mixed get($key) $key = { id, titre, message }
     */
    class ArticleDto extends Dto {
       function __construct() {
          parent::__construct(array('id', 'titre', 'message'));
       }
    }
     
    $a = new ArticleDto();
    $a->set('id', 123);  // équivalent
    $a->id = 123;        // équivalent

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Merci pour vos conseils ;-)

    Mais on est bien d'accord, que cette remarque :
    Citation Envoyé par rawsrc Voir le message
    Citation Envoyé par Benjamin Delespierre Voir le message
    Je pense personnellement que l'internationalisation n'a rien à voir avec le modèle à moins que ce dernier ne soit lui-même multilingue.
    Tout à fait, il ne faut pas vouloir courir plusieurs chevaux à la fois.
    Généralement tout mélanger dans une super classe pour économiser je ne sais quoi est une très mauvaise idée et se termine souvent dans une impasse.

    Ne s'applique pas lorsqu'il s'agit de l’internationalisation de l'objet lui même ?

    Car le modèle "représente" mon article et ce qui le compose donc ses champs multilingues doivent aussi être disponible d'une manière ou d'une autre ?

  11. #11
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Tout à fait, arrange-toi pour pouvoir distinguer les différentes langues d'un même article et le tour est joué (cf mon post plus haut).

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 40
    Points : 26
    Points
    26
    Par défaut
    Oui

    Merci pour la confirmation

  13. #13
    Membre confirmé
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Points : 640
    Points
    640
    Par défaut
    C'est drôle que tout le monde semble avoir opté pour la seconde solution, moi je serais allé vers la première.

    D'une part parce que tu peux contrôler de facon plus granulaire l'accès à chaque données. Par exemple empêcher la mise à jour du prix sans d'abord passer par une méthode de validation et de conversion.

    Ensuite tes objets ont en quelque sorte aucun attribut. Impossible de faire appel à la réflection, de documenter efficacement tes classes (avec phpDocumentor ou un truc du genre), il sera difficile de migrer vers des solutions comme des ORM, ou si jamais tu migre, de laisser d'éventuel frameworks analyser les données de tes classes.

    Et finalement, tu risque de te retrouver à "prostituer" des objets. Je veux dire par là que tu sera dans une situation particulière, et te dira "bof, je vais lui injecter une variable bidon, ca m'évitera de .....". Bref, une porte ouverte à la tentation des mauvaises pratiques.


    Je ne suis pas 100% contre la seconde solution, mais je pense qu'il faut vraiment pouvoir justifier la nécessité d'utiliser cette forme de classe.

  14. #14
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je ne suis pas 100% contre la seconde solution, mais je pense qu'il faut vraiment pouvoir justifier la nécessité d'utiliser cette forme de classe.
    La seconde forme permet d'avoir des attributs dynamiques et donc de factoriser les opérations CRUD inhérentes à toute classe de modèle au sein d'une classe mère commune, ce qui apporte plus de cohérence à l'ensemble de ces classes.

    Si ça te gène à ce point qu'un même accesseur accède indifféremment à n'importe quelle propriété, tu peux utiliser cette forme:
    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
    class Test {
     
      protected $_vars = array();
     
      public function __get ($key) {
        if (method_exists($this, $method = "get{$key}"))
          return $this->$method();
        throw new RuntimeException("No {$method} defined");
      }
     
      public function __set ($key, $value) {
        if (method_exists($this, $method = "set{$key}"))
          return $this->$method($value);
        throw new RuntimeException("No {$method} defined");
      }
     
      public function getA () { return isset($this->_vars['a']) ? $this->_vars['a'] : null; }
      public function getB () { return isset($this->_vars['b']) ? $this->_vars['b'] : null; }
      public function getC () { return isset($this->_vars['C']) ? $this->_vars['c'] : null; }
     
      public function setA ($val) { if (is_string($val)) $this->_vars['a'] = $val; }
      public function setB ($val) { if (is_int($val)) $this->_vars['b'] = $val; }
      public function setC ($val) { if (is_object($val)) $this->_vars['c'] = $val; }
    }
     
    $t = new Test;
     
    $t->A = "hello";
     
    var_dump($t);

Discussions similaires

  1. [POO] Problème: public, protected et private PHP5
    Par fleur_de_rose dans le forum Langage
    Réponses: 5
    Dernier message: 07/05/2006, 19h26
  2. Public Private Protected
    Par Sabrina_of_darkness dans le forum Langage
    Réponses: 1
    Dernier message: 25/03/2006, 22h21
  3. problème de private , public , protected
    Par florantine dans le forum C++
    Réponses: 3
    Dernier message: 17/01/2006, 20h51
  4. [POO] Public Property
    Par MatP dans le forum Langages de programmation
    Réponses: 5
    Dernier message: 27/09/2005, 11h13
  5. Protected / Public / Private....
    Par GOUGOU1 dans le forum C++
    Réponses: 16
    Dernier message: 17/03/2005, 22h04

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