Connaître le parent d'une instance de classe ?

Eléphant du PHP | 92 Messages

20 mai 2009, 17:11

Bonjour,
Dans mon code, j'ai une classe qui crée une instance d'une autre classe. Dans une méthode de celle-ci, je voudrais pouvoir récupérer la valeur d'une variable de sa classe parente (càd celle qui l'a créée). Est-ce que c'est possible ?

Voici un exemple qui vous semblera peut-être plus clair.

Code : Tout sélectionner

class A{ var myvar; function __construct($option){ $this->myvar=$option; $this->sous_classe=new B(); } } class B{ function __construct(){ } } $test=new A('truc');
Je crée donc une instance de A nommée $test, qui va alors créer une instance de B. Et je voudrais, depuis une méthode de B (__construct ou autre), avoir accès à la variable 'myvar' de $test (qui a pour valeur 'truc' dans mon exemple).

Petit nouveau ! | 2 Messages

20 mai 2009, 17:49

Tel que tu le fais là, $this->sous_classe n'est qu'un attribut de ta classe A (au même titre que myVar, au passage, le mot clé var est déprécié me semble t-il).

Tu ne pourras donc récupérer sous_classe directement à l'intérieur de ta classe B.

Tu peux éventuellement créer un attribut statique... il faudrait en savoir plus sur ce que tu souhaites faire pour éviter les soucis de conception.

Eléphant du PHP | 92 Messages

20 mai 2009, 18:08

Tel que tu le fais là, $this->sous_classe n'est qu'un attribut de ta classe A (au même titre que myVar, au passage, le mot clé var est déprécié me semble t-il).

Tu ne pourras donc récupérer sous_classe directement à l'intérieur de ta classe B.
Il n'y a pas un équivalent à $this qui désignerait la classe qui a créé l'instance de la classe courante (dans le cas où elle ait été créée par une classe) ? Quelque chose du genre $parent ?
Tu peux éventuellement créer un attribut statique... il faudrait en savoir plus sur ce que tu souhaites faire pour éviter les soucis de conception.
Je gère des formulaires. J'ai une classe "form" (le formulaire global), une classe "field" (les champs que le formulaire gère) et une classe option (des groupes de checkboxes, radios et selecteurs).
J'ajoute des champs au formulaire via des méthodes qui créent des instances de la classe field (et qui créent elles-mêmes des instances de options pour certains types de champs).
Je gère les erreurs du formulaire dans l'instance de la classe form. Dans un cas un peu particulier, j'ai besoin de récupérer la liste des erreurs (variable $errors de mon instance de form) depuis les instances de mes classes field.
Pour l'instant, j'ai contourné le problème en balançant la variable $errors dans l'instance de chaque classe field que je crée mais je me disais qu'il y avait peut-être un moyen plus propre et plus sûr pour y accéder.

EDIT : en fait, plutôt que de passer la variable $errors, je passe une référence vers $this dans chaque nouvelle instance que je crée. Ça a l'air de marcher tout aussi bien et ça me permet d'accéder à n'importe quelle variable du "parent".

ViPHP
ViPHP | 4674 Messages

23 mai 2009, 15:07

Hey :-),

Attention au vocabulaire utilisé. Le parent d'une classe fille existe lorsque l'on a une relation d'héritage. Tu n'as pas un héritage ici mais une relation (une classe dans une classe). Une relation est un cas particulier d'encapsulation.
Lorsque tu as une relation entre deux classes (que ce soit une agrégation ou une composition, je te laisse chercher sur Google), si tu veux qu'elles se connaissent mutuellement, tu dois passer l'instance ($this) dans le constructeur de l'autre par exemple.

Voyons plutôt :
class Course {

    protected $_vehicule = null;

    public function __construct ( Vehicule $v ) {

        $this->_vehicule = $v;
    }
}

abstract class Vehicule {

    protected $_course = null;

    public function __construct ( ) {

        $this->_course = new Course($this);
    }
}

class Voiture extends Vehicule { }
class Moto extends Vehicule { }
class Roller extends Vehicule { }
class Sandale { }
Ici, je me suis amusé avec un héritage supplémentaire, pour te montrer quelque chose d'intéressant.

On ne peut pas instancier un véhicule car il est abstrait. Par contre, une voiture, une moto et un roller peuvent s'instancier et ils sont de type Vehicule. Une sandale n'est pas un Vehicule, donc on ne pourra pas le donner à une course.

On pourrait finaliser la méthode Vehicule::__construct, mais on ne va pas abuser dans les exemples ;-). On pourra aussi surcharger Vehicule::__construct dans les enfants et utiliser mot-clé parent que tu cherches à utiliser depuis le début mais bref. Tu as des pistes, plusieurs nouveaux mots de vocabulaire. Si tu as des questions, je suis bien sûr tout à fait disposer à y répondre :-).
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Petit nouveau ! | 2 Messages

26 mai 2009, 12:56

Je gère des formulaires. J'ai une classe "form" (le formulaire global), une classe "field" (les champs que le formulaire gère) et une classe option (des groupes de checkboxes, radios et selecteurs).
J'ajoute des champs au formulaire via des méthodes qui créent des instances de la classe field (et qui créent elles-mêmes des instances de options pour certains types de champs).
Je gère les erreurs du formulaire dans l'instance de la classe form. Dans un cas un peu particulier, j'ai besoin de récupérer la liste des erreurs (variable $errors de mon instance de form) depuis les instances de mes classes field.
Vite fait je dirai qu'il te faut un singleton sur ta classe form, tu ne gère qu'un seul formulaire à la fois, n'est-ce pas ?

cela ressemble à ceci :

Code : Tout sélectionner

class Form { private static $instance; function __construct() { $instance = this; } static function GetInstance() { if(!isset(Form::$instance)) { Form::$instance = new Form(); } return Form::$instance; } }
Tu pourra récupérer ton Form à partir de toutes tes sous-classes, donc récupérer tous des éléments de formulaire et leurs erreurs respectives.

Tu récupéreras ton form de n'importe ou avec un "Form::GetInstance()"
Dans l'idée je ferai ça. Fais attention à la syntaxe, je ne suis pas sur de moi n'étant pas un natif de php ;)

Pour récupérer ton attribut errors : Form::GetInstance()->$errors

ViPHP
ViPHP | 4674 Messages

26 mai 2009, 13:10

Euh, un singleton c'est plutôt ceci :
<?php

class The_One {

    /**
     * Notre instance sera stockée ici,
     * et personne n'y a accès à part The_One, soit self ou $this.
     */
    private static $_instance = null;

    /**
     * Notre constructeur est privé.
     */
    private function __construct ( $arg1, …, $argN ) { … };

    /**
      * Notre méthode pour avoir l'instance de la classe.
      */
    public static function getInstance ( $arg1, …, $argN ) {

        if(null === self::$_instance)
            self::$_instance = new self($arg1, …, $argN);

        return self::$_instance;
    }

    …
}
Un peu plus propre.

Par contre, utiliser un singleton pour un formulaire, je trouve qu'on se rapproche de l'erreur de conception là … Un formulaire n'a pas de raison d'être en singleton d'après moi :?.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

26 mai 2009, 15:03

Exact, je confirme. Une classe formulaire doit donner naissance a plusieurs instances (objets) distincts selon les usages des utilisateurs et donc pas de singleton. Par contre, un processus de gestion de pool de connexions à des base de données ou une file d'exécution de requêtes SQL peuvent être vus comme des singletons car cela permet de concevoir des sous-systèmes spécialisés à instances uniques partagées entre les applications.

Voir:http://fr.wikipedia.org/wiki/Singleton_ ... onception)
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène