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] Destruction d'objet et de ses références


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 7
    Par défaut [POO] Destruction d'objet et de ses références
    Bonjour à tous,

    Mon problème est simple mais je ne trouve pas la solution. J'aimerai pouvoir supprimer un objet (et donc appeler sa fonction __destruct()) alors que plusieurs référence lui sont rattachées.

    J'utilise PHP 5.2.10

    Puisqu'un bon bout de code vaux mieux qu'un long discours… si si!
    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
     
    class Object{
    	public static $collection;
    	protected $internal_uuid;
     
    	public static function factory($uuid = null){
    		if(isset(self::$collection[$uuid])){
    			return self::$collection[$uuid];
    		}else{
    			return new Object();
    		}
    	}
     
    	protected function __construct(){
    		$this->uuid();
    		/* Bon je vous copie pas tous le code mais en gros cette fonction affecte,
    		* vous l'aurai compris, un identifiant unique a $this->internal_uuid.
    		*/
     
    		self::$collection[$this->internal_uuid] = $this;
    	} 
     
    	public function __destruct(){
    		echo '__destruct';
    	}
    }
     
    	//Après la déclaration de la classe, ben… on s'en sert.
    $oObject = Object::factory();
    unset($oObject);
    echo '*** FIN DU SCRIPT ***';

    L'exécution de ce bout de code nous donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    *** FIN DU SCRIPT ***
    __destruct

    Ce qui est tout a fait normal car la référence à notre objet se trouve encore dans Object::collection après le unset et c'est donc a la fin de l'exécution du script que l'appel à __destruct se fait.

    Ce que j'aimerai donc obtenir c'est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    __destruct
    *** FIN DU SCRIPT ***
    Avec Object::collection[<identifiant unique de mon instance>] == NULL juste après l'appel de unset($oObject)




    Quelqu'un a-t-il une idée ? Je m'arrache les cheveux la dessus… j'ai essayé dans tous les sens avec référence, sans référence (bon même si elles sont implicite en PHP5)

  2. #2
    Membre très actif Avatar de metagoto
    Profil pro
    Hobbyist programmateur
    Inscrit en
    Juin 2009
    Messages
    646
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Hobbyist programmateur

    Informations forums :
    Inscription : Juin 2009
    Messages : 646
    Par défaut
    Citation Envoyé par Bilhackmac Voir le message
    Quelqu'un a-t-il une idée ? Je m'arrache les cheveux la dessus… j'ai essayé dans tous les sens avec référence, sans référence (bon même si elles sont implicite en PHP5)
    C'est tout à fait normal que ça ne se passe pas comme tu veux.
    self::$collection garde une référence vers ton objet. Quand tu fais ton unset, la référence de $oObject est détruite, mais pas celle dans self::$collection.

    Ton destructeur n'est donc appelé qu'à la toute fin du script, après le dernier echo.

    Ce qu'il faudrait faire, c'est briser la première référence avant le unset.
    Du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public function release() {
      self::$collection[$this->internal_uuid] = null;
    }
    Puis:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $oObject = Object::factory();
    $oObject->release();
    unset($oObject);
    Note que tu ne peux pas mettre l'équivalent de release() dans le destructeur car ce destructeur n'est pas appelé par unset(), mais bien par php à la toute fin.

  3. #3
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Non, mais on peut quand même faire d'une pierre deux couilles :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class Object {
       public static function delete(Object $o) {
             self::$collection[$o->internal_uuid] = null;
             unset($o);
       }
       ...
    }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $o = Object::factory();
    Object::delete($o);

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 7
    Par défaut
    merci de vos réponse mais ce n'est pas exactement ce que je cherche. Ce que je voudrais c'est détruire l'objet à partir d'une ce ses références quelque soit le nombre de référence.

    En partant de ma 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
     
    $ref_x = $ref_y = $ref_z = $oObject = Object::factory();
    unset($oObject);
     
    var_dump($ref_x);
    var_dump($ref_y);
    var_dump($ref_z);
    var_dump(Object::$collection[$uuid/*qui correspondrait à l'uuid de $oObject*/]);
     
    /* Sortie écran */
    NULL
    NULL
    NULL
    NULL

    Je ne sais pas si c'est réalisable en php5, s'il le faut je peux passé en php6.

  5. #5
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 694
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 694
    Par défaut
    Citation Envoyé par Bilhackmac Voir le message
    merci de vos réponse mais ce n'est pas exactement ce que je cherche. Ce que je voudrais c'est détruire l'objet à partir d'une ce ses références quelque soit le nombre de référence.
    je n'ai pas compris, avec ton exemple de code, tu aurais aimé avoir quel résultat ?

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 7
    Par défaut
    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
     
    class Object{
    	public static $collection;
    	protected $internal_uuid;
     
    	public static function factory($uuid = null){
    		if(isset(self::$collection[$uuid])){
    			return self::$collection[$uuid];
    		}else{
    			return new Object();
    		}
    	}
     
    	protected function __construct(){
    		$this->uuid();
    		/* Bon je vous copie pas tous le code mais en gros cette fonction affecte,
    		* vous l'aurai compris, un identifiant unique a $this->internal_uuid.
    		*/
     
    		self::$collection[$this->internal_uuid] = $this;
    	} 
     
    	public function __destruct(){
    		echo '__destruct';
    	}
    }
     
    $ref_x = $ref_y = $ref_z = $oObject = Object::factory();
    unset($oObject);
     
    var_dump($ref_x);
    var_dump($ref_y);
    var_dump($ref_z);
    var_dump(Object::$collection[$uuid/*qui correspondrait à l'uuid de $oObject*/]);
    Avec ce code, et sans faire un unset sur chaque référence, j'aimerai avoir une sortie écran du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    __destruct
    NULL
    NULL
    NULL
    NULL
    bien sur ce n'est pas ce que j'obtient actuellement


    [edit] je voudrai que mes références se comportent comme des pointeurs en C++ (si mes base de c++ sont bonnes)

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

Discussions similaires

  1. [POO] destruction d'objet ?
    Par karibouk dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 21/01/2009, 11h36
  2. [POO] Destruction d'objet
    Par Kephuro dans le forum Langage
    Réponses: 6
    Dernier message: 07/06/2008, 01h24
  3. [POO] cloner un objet (et tous ses sous objets ?)
    Par Merfolk dans le forum Langage
    Réponses: 11
    Dernier message: 05/05/2008, 16h23
  4. Réponses: 4
    Dernier message: 29/11/2007, 01h52
  5. [POO] Destruction d'objet php
    Par krfa1 dans le forum Langage
    Réponses: 5
    Dernier message: 18/01/2007, 21h18

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