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] cloner un objet (et tous ses sous objets ?)


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Merfolk
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    170
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 170
    Par défaut [POO] cloner un objet (et tous ses sous objets ?)
    Hello


    j'ai des difficultés à utiliser la méthode clone... mon but est de dupliquer un objet "full" , dupliquer aussi tous les objets qu'il contient, et encore chaque sous objet, et sous sous objet...

    j'y arrive en faisant un serialize/ unserialize, mais je pense que c'est peut être un goulot d'étranglement.

    J'ai vu qu'il y avait une méthode clone...mais je ne comprends pas comment elle marche.


    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
     
     
    // recupere un autre objet jeu
    function cloner()
    {
    		/* fonctionne */
     		$nouveauJeu=new jeu(false);
    		$tmp=serialize($this->listePieces);
    		$nouveauJeu->chargerPieces($tmp); // fait $this->listePieces = unserialize..
    		return $nouveauJeu;
     
     
                    /* ne fonctionne pas, les sous objets ne sont pas clonés apparement */
    		return clone($this);
     
                    // $this->listePieces est un tableau d'un autre objet, Piece, qui lui aussi contient pleins d'autres objets...
    }


    merci

  2. #2
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2006
    Messages : 317
    Par défaut
    Il faut utiliser la methode magic __clone.

    Voici un exemple de code qui marche.
    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
     
    class jeu{
        public $pieces;
        public function chargerPieces($a_piece){
            $this -> pieces = $a_piece;
        }
     
        public function __clone() 
        {  
           $size = count($this -> pieces);
           for($i=0; $i<$size; $i++){
                $this ->pieces[$i] = clone $this ->pieces[$i];
           }
        }
    }
     
    class piece{
        public $valeur;
        public function __construct($valeur){
            $this -> valeur = $valeur;
        }
    }
     
    $pieces = array();
    $pieces[] = new piece('carte rouge');
    $pieces[] = new piece('carte bleu');
    $pieces[] = new piece('carte bleu');
     
    $jeu = new jeu();
    $jeu -> chargerPieces($pieces);
    $jeu2 = clone $jeu;
     
    var_dump($jeu);
    echo '<br /><br /><br />';
    var_dump($jeu2);
    echo '<br /><br /><br />';
     
    $jeu2-> pieces[1] -> valeur = 'fausse carte';
     
    var_dump($jeu);
    echo '<br /><br /><br />';
    var_dump($jeu2);
    echo '<br /><br /><br />';

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 448
    Par défaut
    En complément je dirais que la méthode __clone qui est défnis dans tes classes est la méthode qui est appelée par PHP lorsque tu appelles la fonction clone ainsi :
    clone($toto);
    ou $toto est une instance d'une classe.

    Si tu ne définis pas cette méthode, j'imagine que PHP clone l'objet sans cloner les objets à l'intérieur, et fais donc des références.

    tu fera attention, on parle bien de la méthode __clone et de la fonction clone, qui sont toutes deux différentes.

    voiilà, simple précision.

    bye

  4. #4
    Membre confirmé Avatar de Merfolk
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    170
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 170
    Par défaut
    ok

    juste un précision :
    si je comprends bien je dois aussi définir __clone dans piece pour tous ses objets, et ainsi de suite ?

    sinon j'avoue j'ai du mal à comprendre le code là
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function __clone() 
        {  
           $size = count($this -> pieces);
           for($i=0; $i<$size; $i++){
                $this ->pieces[$i] = clone $this ->pieces[$i];
           }
        }
    c'est une méthode qui est appelée par qui ?
    par le nouvel objet ? ou l'ancien ?

    enfin si je compare à c++ les constructeurs de recopie tout ça, ben il manque un parametre là, non ? quel est le nouvel objet, quel est "la source" ?
    je ne comprends pas cette ligne par exemple
    $this ->pieces[$i] = clone $this ->pieces[$i];


    merci

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 448
    Par défaut
    juste un précision :
    si je comprends bien je dois aussi définir __clone dans piece pour tous ses objets, et ainsi de suite ?
    Oui.

    c'est une méthode qui est appelée par qui ?
    par le nouvel objet ? ou l'ancien ?
    Pour ce que j'en sais, aucun des deux, c'est PHP qui prend en charge la duplication et qui execute les appels à la méthode __clone lorsqu'elle est définie. Dans le cas contraire PHP utilise sa propre méthode de clonage.

    enfin si je compare à c++ les constructeurs de recopie tout ça, ben il manque un parametre là, non ? quel est le nouvel objet, quel est "la source" ?
    Je ne connais pas C++, mais d'après ce que j'ai lu, ce langage dispose de trois types de ctors. En PHP il n'y en à qu'un, et pour cloner c'est la méthode dite *magic* qui est appelé. en l'occiurence __clone. L'objet source c'est this car c'est une méthode d'instance. Le nouvel objet c'est ce que la méthode retourne (Au passage, je ne sais pas si PHP émet un warning si on renvoi un type différent.).


    je ne comprends pas cette ligne par exemple
    $this ->pieces[$i] = clone $this ->pieces[$i];
    On pourrait traduire cette ligne ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $this ->pieces[$i] = $this ->pieces[$i]->__clone();
    Si la méthode __clone est définie, bien sûr.

    en espérant que cela t'aides à saisir.

    bye

  6. #6
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    317
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2006
    Messages : 317
    Par défaut
    Les methodes *magic* de php pour les objets sont des methodes dont normalement tu n'as pas à faire l'appel directement.
    Elles reagissent à des evenements.

    Voici quelques exemples :
    __construct : methode appellé a la creation d'un objet
    __get : methode appellé quand on effectue un appel à un attribut inexistant. $objet ->mavariable (sauf que mavariable n'existe pas)
    __set : methode appellé quand on effectue une assignation de valeur à un attribut indexistant ($objet -> mavariable = 1)
    __clone : methode appellé lors du clonage et indiquant les actions specifiques à effectuer en plus du clonage de l'objet (par exemple, cloner tous les attributs si ce sont des objets, tu peux utiliser l'API de reflexion de PHP pour faire ça.)

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

Discussions similaires

  1. Cloner un panel avec tous ses objets
    Par rdemont dans le forum ASP.NET
    Réponses: 3
    Dernier message: 11/07/2010, 21h33
  2. Réponses: 3
    Dernier message: 03/02/2009, 10h54
  3. Lister un répertoire et tous ses sous répertoires dans un treeview
    Par shaun_the_sheep dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/09/2008, 08h37
  4. Copier un dossier dans un répertoire et tous ses sous répertoires
    Par Aiacciu dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 07/01/2008, 21h24

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