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] Portée des objets


Sujet :

Langage PHP

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    77
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 77
    Points : 463
    Points
    463
    Par défaut [POO] Portée des objets
    Bonjour,
    je coince actuellement sur un soucis au niveau de la portée des objets.

    J'ai un fichier index.php dans le quel j'instancie un objet de la classe A et un objet de la classe B:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $a = new A();
    $b = new B();
    Dans ma classe B, j'aimerai bien avoir accès à l'objet $a :
    class B {
    function B() {
    $a->getVar();
    }
    }
    Cependant cela ne marche pas (je m'en doutais un peu). Maintenant le problème est de trouver un moyen pour pouvoir accèder à cet objet $a instancié dans le même fichier que l'objet $b, dans la classe B.

    À part utiliser le mot clé "global" que je serai contraint de rédéclarer dans chaque méthode utilisant l'objet $a, n'y a-t-il pas une autre solution ?

    Parce que certe là ça ne semble pas être très important, mais en réalité j'ai pleins d'objets auxquels je voudrai accéder dans pleins de classes et dans pleins de méthodes. Utiliser le mot clé global à chaque fois est assez génant pour moi.
    N'y a-t-il pas une autre solution ?

    Sinon je peux faire de index.php une classe Index avec deux attributs $this->a (l'objet $a) et $this->b (...) et je fais hériter toute mes classes de Index, et donc je pourrai accéder dans toutes mes classes à mes deux objets comme ça : $this->a->getVar(); par exemple.
    Cette solution est elle meilleure ?
    Cependant elle m'oblige quand même à : 1) employer $this à chaque fois, et 2) à faire hériter toute mes classes de Index.

    Y a t il une solution qui m'aurait échappée ?

    Merci d'avance pour vos réponses.


    PS : sinon il y a la solution d'utiliser le tableau $GLOBALS et de mapper chaque valeur dans une variable, genre $a = $GLOBALS['a'] mais bof bof.

  2. #2
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Ben tu as la première : le mot clé global partout dans les méthodes. Effectivement ca n'est pas génial et puis il faut s'assurer que la variable est vraiment déclarée partout etc, ca peut poser des problèmes.

    Ensuite tu as la solution de passer cette instance de classe en paramètre de chaque méthode. C'est plus clair parce que tu vois le paramètre, quand tu appelles la fonction tu SAIS que tu as besoin de cette autre classe, qu'elles est instanciée vu que tu la passes en paramètre. Mais ca peut etre ennuyeux si t'as 200 méthodes et trois classes utilisées dans chaque méthode.

    Tu peux aussi passer cette instance (de la classe A) au constructeur de la classe B. Comme ca tu ne le passes qu'une fois en paramètre, lors du constructeur, et donc ta classe B contient une "instance de la classe A" dans ses variables.

    Et puis il y a effectivement la solution de faire une classe supérieure qui se charge de contenir une instance de chacune de tes classes indispensables.

    Perso je pencherai pour la solution du constructeur dans la majorité des cas mais parfois ca n'est pas adapté.

  3. #3
    Membre chevronné
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 144
    Points : 2 196
    Points
    2 196
    Billets dans le blog
    3
    Par défaut
    Il ne faudrait pas passer plutôt par un multition ou un truc du genre :

    function B()
    {
    $inst = A::getInstance();

    $mavar = $inst->getVar();
    }


    Je dis ça un peu à l'arrache, voir le cours sur ce site concernant les multitons

  4. #4
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Mai 2002
    Messages : 101
    Points : 118
    Points
    118
    Par défaut
    Effectivement, le plus clair me semble de passer une instance de A au constructeur de B.

    Le global, ça devient vite le souk (et c'est pas propre). Ca peut se justifier si tu as des dépendances croisées (genre A utilise B et B utilise A), encore que...

    Le passage en paramètre, ça fonctionne bien pour un appel ou deux, mais si tu as toujours besoin de A, ça peut vite devenir lourd à implémenter

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Sur le coup, je pensais comme koopajah, passer l'instance de A au constructeur de la classe B. Mais a ce moment la est ce que cela crée un pointeur vers l'instance A dans B, ou est ce que cela créer une autre instance de A propre a B ?

    Sans compter que si on veux faire l'invers (utiliser B das A) cette solution n'est pas valable étant donner qu'il faudra bien en instancier un avant l'autre ^^.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 87
    Points : 102
    Points
    102
    Par défaut
    salut,

    tu peux aussi utilisez un registre (registry). Pas mal utiliser dans les frameworks. Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class A { function getVar() {} ... }
     
    Registry::register('a', new A());
     
    class B {
    function getVar() {
    Registry::get('a')->getVar();
    }
    }
    en fait Registry est une classz "statique" dans lequel tu peux enregistrer des instances de classes et les nommer. Tu peux ensuite accéder à ces instances en utilisant leur nom.

  7. #7
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Tu passes ce qu'on appelle une référence, tu ne crées pas une nouvelle instance.

    Et j'ai du mal a me rappeler d'un cas ou deux classes ont besoin mutuellement l'une de l'autre.

  8. #8
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Mai 2002
    Messages : 101
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par koopajah
    Et j'ai du mal a me rappeler d'un cas ou deux classes ont besoin mutuellement l'une de l'autre.
    J'ai pas de cas "utile" en tête, mais prenons par exemple une classe Enfant et une classe Parent. Selon comment on utilise ces deux classes, elles peuvent mutuellement liées. (De mémoire, un prof nous avait donné l'exemple d'une classe Poule et d'une classe Oeuf, chacune devant être instanciée avant l'autre... quel humour ces profs )

    De manière plus générale, tout système représenté sous forme d'une liste chaînée bi-directionelle implique que A contient une référence à B et B une référence à A. Bien sûr, c'est beaucoup plus simple dans ce cas d'instancier les deux objets et de définir ensuite leur relation via un "set".

  9. #9
    Membre habitué
    Avatar de Amnesiak
    Profil pro
    Inscrit en
    Août 2002
    Messages
    137
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2002
    Messages : 137
    Points : 151
    Points
    151
    Par défaut
    Si j'ai bien compris, le passage d'objets se fait toujours par référence. Pour forcer un passage par valeur, il faut utiliser le mot clé clone

  10. #10
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Mai 2002
    Messages : 101
    Points : 118
    Points
    118
    Par défaut
    Exact. Attention donc aux mauvaises surprises si on modifie l'objet dans une méthode à laquelle il a été passé...

  11. #11
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Citation Envoyé par Amnesiak
    Si j'ai bien compris, le passage d'objets se fait toujours par référence. Pour forcer un passage par valeur, il faut utiliser le mot clé clone
    Si on lit la documentation on voit que les arguments sont toujours passés par valeur faut utiliser & devant pour passer par référence.
    Je le fais tellement souvent que j'avais oublié.

  12. #12
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Mai 2002
    Messages : 101
    Points : 118
    Points
    118
    Par défaut
    Citation Envoyé par koopajah
    Si on lit la documentation on voit que les arguments sont toujours passés par valeur faut utiliser & devant pour passer par référence.
    Je le fais tellement souvent que j'avais oublié.
    Ah ?? J'aurais donné la main d'un pote à couper que c'était comme en C# ou en Java et que c'était passé par référence... C'est marqué où que c'est par valeur ?

  13. #13
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Citation Envoyé par Cold Hand
    Ah ?? J'aurais donné la main d'un pote à couper que c'était comme en C# ou en Java et que c'était passé par référence... C'est marqué où que c'est par valeur ?
    J'aurai pensé que c'était comme le C/C++ moi : que pour les instances d'objet, les tableaux c'était par défaut par référence (comme tu utilises les pointeurs en C/C++ pour ce genre de données c'est par référence).
    Mais d'après la doc
    Citation Envoyé par doc
    Par défaut, les arguments sont passés à la fonction par valeur (donc vous pouvez changer la valeur d'un argument dans la fonction, cela ne change pas sa valeur à l'extérieur de la fonction). Si vous voulez que vos fonctions puissent changer la valeur des arguments, vous devez passer ces arguments par référence.

    Si vous voulez qu'un argument soit toujours passé par référence, vous pouvez ajouter un '&' devant l'argument dans la déclaration de la fonction :

  14. #14
    Membre régulier
    Inscrit en
    Mai 2002
    Messages
    101
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Mai 2002
    Messages : 101
    Points : 118
    Points
    118
    Par défaut
    mmh... La doc parle du passage d'argument pour les fonctions, je ne sais pas si les constructeurs sont englobés dans le tas... D'autant que la phrase

    La valeur par défaut d'un argument doit obligatoirement être une constante, et ne peut être ni une variable, ni un membre de classe, ni un appel de fonction.
    Me laisse sceptique. Bon, à tester quoi...

  15. #15
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    77
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 77
    Points : 463
    Points
    463
    Par défaut
    Merci pour vos réponses.

    Je constate qu'il n'y aucune solution vraiment "simple" et "propre", alors je me dis que je prends peut-être le problème à l'envers.
    Peut-être est-ce un defaut de conception de ma part ?

    En faite, j'ai crée une classe SQLManager (une couche d'asbtraction à la base, je sais qu'il existe PDO, mais là c'est un truc plus léger et adapté à ce dont j'ai besoin).
    J'ai une méthode query() pour executer des requetes. J'ai donc instancié un objet de cette classe : $sql = new SQLManager(); et j'aimerai bien pouvoir faire partout dans mon code $sql->query(); comme j'aurai fait pg_query().
    Après j'ai d'autre classe dans le genre, comme Game : $game = new Game(); et j'aimerai pouvoir utiliser les methodes de mon objet $game partout dans mes autres classes.
    Vous voyez ?
    Je pense que c'est un des interêts de la POO et que je ne suis pas le seul à faire ça. Mais peut-être que je m'y prends mal.

    Est-ce qu'il serait plus judicieux de déclarer mes methodes en static et y accéder avec un simple SQLManager::query();, mais dans ce cas là coment faire pour les attributs de classe....? Genre dans ma classe Site, je charge un fichier de configuration avec loadConfig(); et je remplis les attributs $site->default_theme, $site->default_lang etc...que j'ai besoin à divers endroits du code.

    Est ce qu'il serait plus judicieux de créer un nouvel objet de ma classe SQLManager dans chaque classe...?
    Mais le problème reste le même pour ma classe Site et ses attributs...

  16. #16
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 393
    Points : 15 754
    Points
    15 754
    Par défaut
    je fais quelque chose dans le même genre quand j'utilise des bases de données dans mon code, j'ai une classe BDD avec çà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class BDD
    {
        function & obtientConnexion()
        {
            static $connexion;
     
            if (!isset($connexion)) {
                $connexion =& new BDD();
            }
     
            return $connexion;
        }
    et ensuite dans les classes des objets de ma base je fais "$bdd =& BDD::obtientConnexion();" pour récupérer la connexion à ma base de données
    et comme ça j'ai juste besoin de me connecter une seule fois à la base, ce qui économise des ressources

  17. #17
    Membre expert
    Inscrit en
    Janvier 2005
    Messages
    2 291
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 291
    Points : 3 212
    Points
    3 212
    Par défaut
    Citation Envoyé par mathieu
    et ensuite dans les classes des objets de ma base je fais "$bdd =& BDD::obtientConnexion();" pour récupérer la connexion à ma base de données
    et comme ça j'ai juste besoin de me connecter une seule fois à la base, ce qui économise des ressources
    C'est le principe du pattern singleton ca non? Enfin quelqu'un a parlé plus tot de pattern dans ce thread mais je pense qu'il y a eu confusion. LE but c'est de t'assurer que dans tous tes scripts tu as 0 ou 1 instance de ta classe de base de données en gros.
    Moi je dis +1 !

  18. #18
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 393
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 393
    Points : 15 754
    Points
    15 754
    Par défaut
    Citation Envoyé par koopajah
    C'est le principe du pattern singleton ca non?
    oui c'est ça

    en cadeau la version PHP 5 puisque je suis en train de faire des tests dessus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class BDD
    {
        public static function obtientConnexion()
        {
            if (!isset(self::$bdd)) {
                self::$bdd = new BDD();
            }
     
            return self::$bdd;
        }
     
        private static $bdd;

  19. #19
    Membre chevronné
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 144
    Points : 2 196
    Points
    2 196
    Billets dans le blog
    3
    Par défaut
    Bah oui, singleton ou multiton, c'ets ce que je dis dans le 3ème message laissé dans ce post... mais apparement il est passé à la trappe lol

  20. #20
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    77
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 77
    Points : 463
    Points
    463
    Par défaut
    Merci pour vos réponses.

    J'ai finalement adopté le pattern Registry, qui est +/- ce que j'avais besoin.

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

Discussions similaires

  1. POO -> principe de création des objets
    Par DeeVoiD dans le forum Langage
    Réponses: 5
    Dernier message: 20/11/2009, 09h24
  2. [POO] Récupérer des objets en PHP 4
    Par slyfer dans le forum Langage
    Réponses: 4
    Dernier message: 01/02/2007, 10h22
  3. [POO] PB d'interprétation des '\n' (PHP Objet)
    Par Bobabar dans le forum Langage
    Réponses: 8
    Dernier message: 25/04/2006, 01h08
  4. [FLASH 8] Question sur la portée des objets.
    Par i_shinji dans le forum Flash
    Réponses: 1
    Dernier message: 02/11/2005, 17h18
  5. Réponses: 3
    Dernier message: 17/10/2005, 16h26

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