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] Structurer une classe


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Par défaut [POO] Structurer une classe
    Bonjour,

    Imaginons que j'ai une application PHP qui génère des documents PDF de différents types (facture, devis, rappels, cartes postales, etc...). Tous ces documents ont une base commune, comme l'adresse, la référence du client et même à un niveau plus technique la façon dont ils sont créés.

    L'idée serait donc de créer une classe CDoc, qui contiendrait les méthodes et propriétés communes à tous les types de documents possibles, puis de créer des classes dérivés héritant de CDoc et auxquels ont rajoute leurs informations propres.

    Reste à voir comment on fait ça "bien"...

    1 - en BDD, ai-je raison de créer une table doc (qui contient les infos que l'on retrouve dans tous les soustypes de documents) et une table pour chaque sous type de document (facture, devis, mots_doux, ...) ? Si tel est le cas, dans quel sens est-il le plus judicieux de créer la relation père-fils ? le sous-type appel t-il doc, ou doc doit-il appeler le sous type correspondant (sachant qu'il faut alors un flag de sous-type dans doc) ?

    2 - a l'utilisation, comment instancier mes class en fonction du type ? Faut-il appeler directement le constructeur du sous-type ou existe t-il un moyen d'appeler le constructeur de CDoc et d'instancier la class dérivée adaptée depuis CDoc ?

    En vous remerciant d'avance.

  2. #2
    Membre confirmé Avatar de bigltnt
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    227
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 227
    Par défaut
    Salut.

    Ta question concernant la conception de tes classes relève (à mon avis) des design patterns, qui sont des méthodes de conceptions pour résoudre des problématiques données.

    Impossible de te répondre bien sans taper un article, et je débute en design pattern, mais je dirais pour te donner une piste de voir le pattern "factory" qui peut être une des solutions possibles.

  3. #3
    Membre chevronné
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Par défaut
    Merci pour ta réponse biglInt.

    imaginons un exemple de ce style :

    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
    class CDoc
    {
       function __contruct($id = false) // ouvre le document # $id {...} ou un instancie un nouveau vierge
       virtual function Render() {...} // fonction de rendu en PDF
       function SetAdresse($a) {...}
       function GetAdresse() {...}
       function SetDate($d) {...}
       function GetDate() {...}
    }
     
    class CFacture extends CDoc
    {
       function Render() {...}
       function SetMontant($cash) {...}
       function SetSiret($n) {...}
    }
     
    class CCarteDeVoeux extends CDoc
    {
       function Render() {...}
       function SetImage($i) {...}
       function SetTexte($t) {...}
    }
    Si je me fie a ton lien, l'idée serait de faire une class CDocumentFactory qui va se charger de me renvoyer ce qu'il faut au travers de méthodes style GetFacture() ou GetCarteDeVeoux() ? Soit, mais quid de ma BDD ?

    Car mon problème reste entier, et je ne sais toujours pas (par exemple) si il est préférable de fonctionner avec un numéro de document unique, ou un numéro de sous document unique pour chaque sous type... (et j'aimerai bien avoir des avis sur cette question)

    Donc je vois au moins 3 façons de faire :

    1)
    doc(id_doc (INT), adresse_doc (VARCHAR), date_doc(TIMESTAMP));
    facture(id_facture (INT), #id_doc (UNIQUE INT), montant_facture (FLOAT), siret_facture(VARCHAR) );
    carte(id_carte (INT), #id_doc (UNIQUE INT), imagecarte(IMAGE), texte(VARCHAR));

    2)

    Soit je fait la même en positionnant une clefs étrangère non unique (ce qui me retire ma contrainte de cardinalité 1,1) dans "doc" plutot que dans les sous types "carte" et "facture"...

    3)

    Soit je créé pas du tout de table doc et je redéclare toutes les données pourtant communes a tous les sous types dans chaque sous types, me privant de fait d'un numéro unique pour chaque document généré puisqu'on pourra avoir des cartes et des factures ayant le même ID...

    sachant que le but est d'avoir au final une BDD et une structure objet "qui vont bien ensemble" !

    En te remerciant pour ton temps.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 138
    Par défaut
    Salut,

    Ton problème, je l'ai eu moi aussi, donc je vais te donner la solution que j'ai trouvé pour moi, même si je ne sais pas si elle est "bonne" ou pas, cependant, je n'ai aucun pb pour coder, et tout fonctionne le mieux du monde.

    Tout d'abord, chaque classe correspond à une table de ta bdd, c'est de ce principe de base dont je suis parti.

    Comme toute table de ta bdd est une classe, alors tes clefs étrangères seront bien souvent des classes filles.

    En reprennant :
    doc(id_doc (INT), adresse_doc (VARCHAR), date_doc(TIMESTAMP));
    facture(id_facture (INT), #id_doc (UNIQUE INT), montant_facture (FLOAT), siret_facture(VARCHAR) );
    carte(id_carte (INT), #id_doc (UNIQUE INT), imagecarte(IMAGE), texte(VARCHAR));
    doc est une classe car c'est une table. De plus elle ne possède pas de clefs étrangères, donc c'est une classe principale.
    facture partage une clef étrangère qui est de plus la PK de doc, ainsi facture est une classe et hérite de doc.
    Ce raisonnement est valable pour carte.

    Ainsi tu auras ta classe mère (doc), deux classes filles (factures, carte).

    Côté technique pour la POO, tu dois avoir autant d'attributs que de champs. Alors pour doc ...

    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
     
    <?php
    //id_doc (INT), adresse_doc (VARCHAR), date_doc(TIMESTAMP)
    class Doc{
    private $id_doc;
    private $adresse_doc;
    private $date_doc;
    public static $temps = time();
     
    public function __construct($id_doc){
    Doc::Creation_obj($id_doc);
    }
     
    public static Creation_obj($id_doc){
    //Tu fais ta requête pr récupérer les attributs via ta bdd
    $this->id_doc = $data['id_doc'][0];
    $this->adresse_doc= $data['adresse_doc'][0]
    $this->$date_doc = $data['date_doc'][0]
    }
     
    //Tu dois aussi préparer une fonction pour insérer ton objet dans ta bdd, le modifier et l'update => Toutes ces méthodes sont static.
     
    //Fais les get-ers & set-ers
     
    //ne pas oublier __destruct qui unset() tous les attributs.
    }
    ?>
    Pour te rendre compte, voici un petit bout de script que j'ai déjà utilisé.

    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
    56
    57
    58
    59
     
    class Commentaire{
     
    	private $id_commentaire;
    	private $id_utilisateur;
    	private $id_galerie;
    	private $date;
    	private $phrase;
     
    	public function __construct($id_commentaire){
    		$this->id_commentaire = $id_commentaire;
    		$this->Set_COM($id_commentaire);
    	}
     
    	private function Set_COM($id_commentaire){
    		$requete = new Requete('commentaire');
    		if($tab = $requete->Select('id_utilisateur,id_galerie,date,phrase', "id_commentaire='$id_commentaire'")){
    		}
    		else{
    			return false;
    		}
    		$this->id_utilisateur = $tab['id_utilisateur']['0'];
    		$this->id_galerie = $tab['id_galerie']['0'];
    		$this->date = $tab['date']['0'];
    		$this->phrase = $tab['phrase']['0'];
    	}
     
    	public static function Ajouter_Commentaire($id_utilisateur,$id_galerie,$phrase){
    		$date = date("Y-m-d");
    		$requete = new Requete('commentaire');
    		if($requete->Insert("'','$id_utilisateur','$id_galerie','$date','$phrase'")){
    			return true;
    		}
    		else{
    			return false;
    		}
    	}
     
    	public static function Modifier_Commentaire($id_commentaire,$phrase){
    		$requete = new Requete('commentaire');
    		if($requete->Update('phrase', $phrase, "id_commentaire='$id_commentaire'")){
    			return true;
    		}
    		else{
    			return false;
    		}
    	}
     
    	public static function Supprimer_Commentaire($id_commentaire){
    		$requete = new Requete('commentaire');
    		if($requete->Delete("id_commentaire='$id_commentaire'")){
    			return true;
    		}
    		else{
    			return false;
    		}
    	}
     
    //Je coupe le code ici ensuite tu as les fonctions basiques de la POO

    Ensuite tu appliques le même système pour les classes filles et tu obtiens un code plutôt efficace.

    Pour récupérer l'id nécessaire à la création de ta classe, tu dois passer par des fonctions "normales", ou faire un petit script que tu inclus dans ta page.

    Je sais pas si ca va t'aider, mais comme on dit, c'est l'intention qui compte

  5. #5
    Membre éclairé Avatar de kanzarih
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Novembre 2002
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Novembre 2002
    Messages : 327
    Par défaut
    Moi j'aurai cherchez une solution du coté du XML XSL : voir ici

    http://bob.developpez.com/phpxslt/

    car enfin du compte ca revient a un problème de présentation de données, non?

    Bon codage

  6. #6
    Membre chevronné
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    504
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 504
    Par défaut
    Merci pour vos réponses ! T'inquiète pas pour le code Evilam, c'est juste histoire de recueillir des avis sur la meilleure façon de faire, pas sur le code à écrire . Apres, la syntaxe, c'est du gateau !

    Par contre, je suis pas ultra expert en POO (les notions quoi), et soit y'a un truc qui m'échappe, soit y'a un truc pas cohérent quand tu écris sur tes méthodes statiques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public function __construct($id_doc){
    Doc::Creation_obj($id_doc);
    }
    Ou tu récupères le retour de Creation_obj si c'est une méthode static ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public static Creation_obj($id_doc){
    //Tu fais ta requête pr récupérer les attributs via ta bdd
    $this->id_doc = $data['id_doc'][0];
    $this->adresse_doc= $data['adresse_doc'][0]
    $this->$date_doc = $data['date_doc'][0]
    }
    un $this dans une méthode static, ça me parait super bizar quand même !

    Sinon, non, c'est pas du tout un problème de présentation des données, mais un problème de stockage et de référencement dans ma BDD... Au final, si j'opte pour la solution que j'évoquais plus haut (clef etrangere pour les classes dérivées), vaut-il mieux ensuite que je référence mes documents par ID de doc (CDoc) ou par ID type de sous document (CFacture, CCarteDeVoeux, etc...) ? Genre dans ma table "expedition", est-ce que je fait une clef vers la table "facture" ou une clef vers la table "document" (sachant que de toute façon, y'a un lien entre un document et son sous type, en l'occurrence facture)

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 138
    Par défaut
    Re,

    (dsl pr la méthode statique avec les $this, j'ai vraiment tapé ca en 3 sec ^^).

    Et pour ta dernière question ... ne serait-il pas facile de classer par ID type de sous document ? Tu alloues un certain espace pour chaque type de document pour éviter que les id(s) se croisent, et il ne devrait pas y avoir de pb.

    Par exemple, entre 0-100 000 tu réserves ca pr les id_factures, 100 001-200 000 pour les id_cartes, etc...

    Ca te fera une table expedition ...

    id_expedition -> 1
    id_ss_doc -> 1 003

    id_expedition -> 2
    id_ss_doc -> 1 004

    id_expedition -> 3
    id_ss_doc -> 116 032

    Ca te fait donc 2 factures et une carte. C'est p-e un peu dépassé comme méthode, enfin je sais pas trop.

    (Ce poste servait surtout à m'excuser pour ma gaffe )

    See you

Discussions similaires

  1. [POO] POO pour une classe PDO
    Par nabab dans le forum Langage
    Réponses: 2
    Dernier message: 08/08/2007, 00h58
  2. Réponses: 3
    Dernier message: 27/04/2007, 15h51
  3. [POO] Compléter une classe existante
    Par poukill dans le forum C++
    Réponses: 5
    Dernier message: 07/03/2007, 14h28
  4. Réponses: 5
    Dernier message: 15/08/2006, 11h40
  5. [POO] Ecrire une classe descendante
    Par GLDavid dans le forum Langage
    Réponses: 4
    Dernier message: 14/10/2005, 20h04

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