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] Classe perso se servant de DOM, passage d'objet


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut [POO] Classe perso se servant de DOM, passage d'objet
    Salut,

    Je souhaite me servir du DOM par l'intermédiaire d'une classe personnelle.

    Seulement je ne désire absolument pas mettre mes attributs en public, et cela me pose problème, car je ne sais pas de quel manière résoudre le passage de l'objet.

    Un exemple de 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
    <?php
     
    class page
    {
       private $xml;
       private $page;
       private $head;
       private $contenu;
       private $title = false;
       private $h1 = false;
       function __construct()
       {
          $this->xml = new DOMdocument('1.0', 'iso-8859-1');     
          $this->page = $this->xml->appendChild($this->xml->createElement('page'));      
          $this->head = $this->page->appendChild($this->xml->createElement('head'));      
          $this->contenu = $this->page->appendChild($this->xml->createElement('contenu'));
          return $this->contenu;   
       }
     
       function ajoutNoeud($tag)
       {
          return $this->contenu->appendChild($this->xml->createElement($tag));
       }
     
       function title($val)
       {
          $this->head->appendChild($this->xml->createElement('title', $val));
          $this->title = true;
       }
     
       function __destruct()
       {
          echo htmlspecialchars($this->xml->saveXML());
       }   
    }
     
    $page = new page();
     
    $page->title('accueil');
     
    // Ok
    $truc = $page->ajoutNoeud('truc');
     
    // Erreur logique
    $truc2 = $truc->ajoutNoeud('truc2');
     
    /*
    // Avec attributs "contenu" et "xml" en public 
    for( $i=1; $i<=10; $i++ )
    {
       $page->contenu->appendChild($page->xml->createElement('item', $i));
    }
    */
     
    ?>
    Donc dans ce code, $truc = $page->ajoutNoeud('truc'); fonctionne normal, mais si je veux rajouter un noeud à $truc, ce n'est pas possible.

    Dans ma méthode ajoutNoeud(), je ne sais pas comment retransmettre mon objet.

    Il faudrait donc que dans return $this->contenu->appendChild($this->xml->createElement($tag));

    Que $this->contenu soit remplacer par l'objet que j'ai, donc $truc dans mon exemple.

    Une idée de comment faire ceci ?

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

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 333
    Points : 15 677
    Points
    15 677
    Par défaut
    c'est peut-être ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public function ajoutNoeud($tag)
    {
        $element = $this->xml->createElement($tag);
        $this->contenu->appendChild($element);
     
        return $element;
    }

  3. #3
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Merci, mais non, ce n'est pas possible comme ça, j'obtiens d'ailleurs la même erreur qu'avec mon code.

    J'ai tenté en repassant l'objet en argument :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function ajoutNoeud($tag, $obj)
    {
        return $this->${$tag} = $obj->appendChild($this->xml->createElement($tag));
    }
     
    // Appel
    $truc = $page->ajoutNoeud('truc', $page);
    $truc2 = $truc->ajoutNoeud('truc2', $truc);
    Mais j'obtiens comme erreur : Call to undefined method page::appendChild()

    Je n'y arrive vraiment pas

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

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 333
    Points : 15 677
    Points
    15 677
    Par défaut
    la méthode "ajoutNoeud" fonctionne seulement sur les instances de la classe "page"
    avec ce que tu veux faire il faudra que tu crées une nouvelle classe "Noeud" par exemple

  5. #5
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Y'a pas d'autres solutions que ça

    Ca va quand même être lourd de faire ceci.

    Donc si j'ai bien compris ce que tu me dit, il faut que je passe une seconde classe, et il faut que je l'instancie dans ma méthode.

    Mais pour ajouter un noeud, il va falloir que dans cette nouvelle classe se fasse une nouvelle instanciation de DOM non ?

    J'ai du mal à concevoir le tout.

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

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 333
    Points : 15 677
    Points
    15 677
    Par défaut
    Citation Envoyé par Xunil
    Mais pour ajouter un noeud, il va falloir que dans cette nouvelle classe se fasse une nouvelle instanciation de DOM non ?
    non ce n'est pas trop objet ça
    dans ce cas tu auras 3 classes, un classe qui instancie l'objet DOM, un classe Noeud et une classe Page qui hérite de Noeud

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Mai 2006
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 206
    Points : 319
    Points
    319
    Par défaut
    Mmmh en fait lorsque tu exécute ta fonction ajoutNoeud() avec $truc, tu renvoi un élément DomNode qui appartient a la classe DOM de PHP et non à ta classe Page, donc tes méthodes n'existeront pas dans cet objet.

    Il faut souvent assembler à l'envers en XML :
    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
    <?php
    $page = new Page();
     
    //Classe DOM pour créer les éléments
    $dom = new DOMDocument('1.0', 'iso-8859-1');
     
    //On créer les deux éléments
    $truc2 = $dom->createElement( $truc2, 'contenu texte' );
    $truc = $dom->createElement( $truc, 'contenu texte' );
     
    $newtruc = $truc->appendChild( $truc2 ); /*Ici $truc2 devient un enfant de 
    $truc. Donc maintenant $truc est un élément de nom $truc qui contient un 
    enfant du nom $truc2 ( on peut imaginer un TD dans un TR en HTML)
    $newtruc est identique à $truc2, la fonction appendChild() renvoi toujours 
    l'élément qui à été ajouté.
    
    Aussi tu modifie ta fonction pour qu'elle ne créer pas d'élément mais 
    simplement ajouter un enfant, elle n'est pas obligée de renvoyer quelque 
    chose, de toute maniere elle te renverra le nouveau noeud créer qui sera 
    une instanciation de la classe DomNode. */
     
    function ajoutNoeud($tag)
    {
          $this->contenu->appendChild( $tag );
    }
     
    // Puis tu assemble le tout dans ton arbre XML de la classe Page :
    $page->ajoutNoeud( $truc );
    ?>
    Au lieu de créer la variable $dom dans le fichier source, tu pourrait le rajouter en attribut de classe mais publique cette fois, car de toute manière ton fichier XML qui doit être affiché sera sauvegarder dans $xml, ainsi tu pourra te servir de $dom pour créer les éléments et les assembler avant d'appeller tes fonctions .

    Voici un petit code d'exemple que je viens de faire, création et affichage d'une page HTML en DOM, tu comprendra peut-être mieux le principe :
    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
    <?php
    //Classe DOM pour créer les éléments et afficher l'arbre final.
    $dom = new DOMDocument('1.0', 'iso-8859-1');
     
    //On créer les éléments
    $htmlElement = $dom->createElement( 'html' );
    $headElement = $dom->createElement( 'head' );
    $titleElement = $dom->createElement( 'title', 'Dom Test' );
    $bodyElement = $dom->createElement( 'body' );
    $tableElement = $dom->createElement( 'table' );
    $trElement1 = $dom->createElement( 'tr' );
    $trElement2 = $dom->createElement( 'tr' );
    $tdElement1 = $dom->createElement( 'td', 'Element TD 1' );
    $tdElement2 = $dom->createElement( 'td', 'Element TD 2' );
     
    //Assemblage de la balise head et title
    $headElement->appendChild( $titleElement );
     
    //Assemblage du tableau, en commencant par les lignes
    $trElement1->appendChild( $tdElement1 );
    $trElement2->appendChild( $tdElement2 );
     
    //Puis on assemble les lignes dans le tableau, l'ordre d'assemblage est important
    $tableElement->appendChild( $trElement1 );
    $tableElement->appendChild( $trElement2 );
     
    //On attache le tableau dans la balise BODY
    $bodyElement->appendChild( $tableElement );
     
    //On assemble maintenant HEAD et BODY dans l'élement HTML, qui 
    //sera la racine du document HTML. L'ordre est toujours aussi 
    //important, HEAD se situe avant BODY.
    $htmlElement->appendChild( $headElement );
    $htmlElement->appendChild( $bodyElement );
     
    //Puis dernier assemblage dans le dom :
    $dom->appendChild( $htmlElement );
     
    //Affichage de la page internet avec un seul et unique echo.
    echo $dom->saveXML();
    ?>
    J'ai remarquer en fesant ce code qu'un élément ne peut être attaché qu'une seule fois à un autre élément, si tu veut attaché plusieurs éléments identique à différents éléments, il faudra les cloner, c'est pas bien dur :
    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
     
    //Ici $tdElement1 sera attaché à $trElement2 mais pas à $trElement1
    $trElement1->appendChild( $tdElement1 );
    $trElement2->appendChild( $tdElement1 );
     
    //Ici pareil qu'au dessus, sa ne marchera pas
    $testNode = $trElement1->appendChild( $tdElement1 );
    $trElement2->appendChild( $testNode );
     
    //Ici sa marchera :) car on créer un nouvel élément.
    $trElement1->appendChild( $tdElement1 );
     
    //le paramètre de la fonction lui indique si il doit cloner les sous-enfants avec
    //ou non.( on pourrait cloner un élément TABLE sans prendre ses enfants TR)
    $tdElement1Clone = $tdElement1->cloneNode( true );
    $trElement2->appendChild( $tdElement1Clone );
    ?>

  8. #8
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Merci mathieu, mais après avoir essayé 1 milliard de combinaisons, je n'ai droit qu'à des erreurs, je commence à douter fortement que ce soit possible de faire ça.

    Peut-être que c'est con, mais je vais pas me servir du DOM pour faire ça, tant pis, à coups de tableaux et d'expressions régulières, je me casserais moins la tête que de me servir du DOM qui lui vient de me réduire le cerveau en bouillie.

    meliandah, c'est sympa ton code , mais ça ne m'aide pas dans mon problème.

    Ce que tu me montres, je n'ai pas de problème à le faire, ce qui me le pose, c'est son implémentation dans une classe utilisateur.

  9. #9
    Membre averti

    Profil pro
    Inscrit en
    Mai 2006
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 206
    Points : 319
    Points
    319
    Par défaut
    Oué je sais jy réfléchis pas mal aussi en ce moment pour essayer de créer une classe qui permetterai de créer une page internet uniquement en PHP avec un seul et unique echo final, mais sa à l'air très complexe à mettre en oeuvre et je soupçonne fortement l'obligation d'utiliser les références (donc sa complique encore plus).
    Et l'autre problème majeur est qu'il faut respecter un ordre rigoureux dans l'ajout des éléments XML à l'arbre, au final je me demande si ce ne serait pas plus simple de faire une classe ou plusieurs qui permettent de créer des éléments HTML, tu renvoi les références et tu assemble le tout manuellement dans le fichier source ou une autre classe ptet.
    C'est vrai qu'en réfléchissant la on essaye de combiner toutes les fonctions DOM dans une classe mais l'ordre étant très important je ne pense pas que cela soit réalisable, je pense opter pour des classes qui créent les éléments séparement, comme une classe permettant de générer des tableau HTML de manière dynamique (c'est possible), avec des paramètres aussi dynamique (fonction magique __call), tu retourne la référence de l'element TABLE auquel les ligne et cellules sont déjà assemblées. Et après tu assemble manuellement le tableau la ou il faut.

  10. #10
    Membre éclairé
    Inscrit en
    Septembre 2006
    Messages
    685
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 685
    Points : 658
    Points
    658
    Par défaut
    Une classe qui génère ma page en html, j'en ai déjà une, mais je veux tenté de le faire en xml avec la librairie xsl de php pour voir ce que ça donne.

    L'ordre ne me pose personnellement pas problème car les seuls ajouts se feront dans le contenu de la page, le reste de la page sera gérer par diverses fonctions réservées à ces usages.

    J'ai essayé aussi d'en passer par __call(), les références, une méthode statique, bref tout un tas de chose, sans résultat évidemment

    Chaque fois j'ai une erreur me disant que dans la classe DOMx la méthode Y n'existe pas ou alors le contraire que la methode DOM->X() n'existe pas dans ma classe, et ce même en y mettant un héritage de DOM dans ma classe

    J'en ai marre de me manger que des erreurs.

    Pas facile quand même

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

Discussions similaires

  1. Passage d'un tableau de class perso
    Par Sebeee dans le forum Services Web
    Réponses: 1
    Dernier message: 22/03/2011, 14h56
  2. Réponses: 3
    Dernier message: 19/05/2005, 10h46
  3. [VB.NET] Instanciation objet (sur class perso.)
    Par DaxTaz dans le forum ASP.NET
    Réponses: 4
    Dernier message: 03/05/2004, 11h07
  4. [ JSP ] [ Tomcat ] importer une classe perso
    Par captainpouet dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 11/03/2004, 11h30

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