|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||
|
Futur Membre du Club
![]() |
Bonjour,
Je m'interroge sur la meilleure façon de modéliser une relation "1 à plusieurs" classique. Prenons par exemple le blog dans lequel un billet peut avoir plusieurs commentaires (avec une classe Billet et une classe Commentaire). Solution 1 : Code :
Code :
De plus, ça me semble plus dans le concept objet de passer l'objet Billet à l'objet Commentaire : de cette façon la classe Billet ne s'occupe que la table Billet et la classe Commentaire de la table commentaires. Qu'en dites-vous ? Merci d'avance. Franck. |
||||
|
00
|
|
|
#2 | |||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Hello
En effet, au sens objet, la relation 1-n se caractérise par une aggregation (un objet porte l'instance de plusieurs autres). Au sens d'une base de données relationnelles, ça se caractérise par une clé étrangère (avec eventuellement une contrainte sur cette clé). Moi je verrai ça comme ça: Code :
Code :
Citation:
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|||||
|
00
|
|
|
#3 | ||
|
Futur Membre du Club
![]() |
Salut Benjamin,
Alors là, ya quelque chose qui m'échappe complètement : j'ai bien compris que SplObjectStorage allait me permettre de stocker les objets commentaires dans mon objet billet, mais je n'en vois pas du tout l'utilité ! Car je dois créer un objet commentaire qui doit être passé à $billet->ajouterCommentaire(), hors, pour créer un objet commentaire j'ai besoin de l'ID du billet concerné. Ce qui donnerait ceci : Code :
Merci d'avance. Franck. |
||
|
00
|
|
|
#4 | |||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Tu m'a dis dans ton premier post que tu modélisait une relation 1-n. Donc dans le cadre des classes Billet et Commentaire, ça s'exprime par "un billet à plusieurs commentaire" et "un commentaire porte sur un et un seul billet".
Donc la classe Billet doit se munir d'une méthode obtenirCommentaires (ou getComments) et la classe Commentaire peut se munir d'une méthode obtenirBillet (ou getArticle). Effectivement, ça marche dans les deux sens, mais fait attention au nombre d'instances: Code :
Le pattern IdentityMap peut t'aider à résoudre ce genre de problèmes: martinfowler.com/eaaCatalog/identityMap.html Citation:
que $commentaire = new Commentaire($billet, 'un commentaire'); Ainsi, la classe commentaire n'a pas besoin de savoir sur quel billet elle porte, c'est la classe Billet qui s'occupe de ses propres commentaires. Pour résumer, je penche davantage pour l'approche "un billet porte n commentaire" plutôt que "un commentaire porte sur un billet" car c'est plus simple de gérer des billets que des commentaires. Au niveau des vues ça fait sens: Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|||||
|
00
|
|
|
#5 |
|
Futur Membre du Club
![]() |
Le problème est que pour pouvoir faire $billet->ajouterCommentaire($commentaire), je dois instancier un objet $commentaire auparavant.
Et donc faire $commentaire = new Commentaire($billet, 'un commentaire') Que penses-tu de passer les données au lieu de l'objet à la fonction, comme ceci : Code :
$billet->ajouterCommentaire('commentaire', 'auteur'). |
|
00
|
|
|
#6 | ||||
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 707 ![]() |
Salut
Si l'ajout d'un commentaire doit avoir un ID de billet et un contenu, alors faut juste renseigner ces 2 données, non ? Code :
Code :
En tout cas, si 1 billet doit avoir une collection d'Objets Commentaire, Billet::ajouterCommentaire() devient obligatoire, car dans ton exemple de code, $commentaire est totalement isolé, ne fait pas partie de $billet. Disons que j'interviens aussi pour dire que je viens de découvrir SplObjectStorage grâce à ce topic, je pense que ça va m'être utile.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
||||
|
|
00
|
|
|
#7 |
|
Futur Membre du Club
![]() |
J'ai également découvert SplObjectStorage grâce à Benjamin. Je vais y jeter un oeil, enfin, quand j'en aurais finis avec ce topic, grrr.
Ta solution première solution me semble la plus efficace, et la plus simple RunCodePhp. Mais une fois que tu as appelé new Commentaire(array($billet->getID(), 'commentaire')), ton commentaire est lié au billet (dans la base). La fonction $billet->ajouterCommentaire($commentaire) me semble donc superflue. Il suffirait juste d'une fonction $billet->getCommentaires() et le tour est joué. Qu'en dites vous ? |
|
00
|
|
|
#8 | ||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Je rebondis sur vos proposition.
Je pense que Billet::ajouterCommentaire peut avoir les deux signatures; ça se modélise comme ça: Code :
Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||||
|
00
|
|
|
#9 | ||||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Appendum: SplObjectStorage est une super classe pour gérer des objets mais ce n'est pas une hashmap !! Si votre but est de retrouver vos petits par un système clé valeur, l'idéal reste le bon vieux tableau.
Vous remarquerez par ailleurs que SplObjectStorage est un itérateur, ça va bien nous servir pour créer des fonctions de filtrage par exemple: Code :
Code :
il existe tout un tas d'itérateur pour tous les usages, filtres, limites, XML et j'en passe... Pour pouvoir utiliser cette merveille de technologie que nous envie la Nasa, il faut que votre objet Traversable implémente l'interface Iterator. Dans le cas d'un tableau associatif, vous pouvez passer par un ArrayIterator ou un ArrayObject comme ceci: Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||||||
|
00
|
|
|
#10 | |
|
Expert Confirmé
![]() Inscription : janvier 2010 Messages : 2 707 ![]() |
Citation:
Quand on appel : new Commentaire(...), le commentaire et certes créé coté Bdd, mais ne fait absolument pas partie de l'Objet $billet en court. Du coup, si tu appel Billet::getCommentaires(), ça va rien renvoyer du tout vu qu'aucun Objet Commentaire à été ajouté, je dis bien Objet. C'est peut être ça qui te turlupine : Billet::getCommentaires() renvoie uniquement des Objets Commentaires, donc coté traitements n'effectue pas de requêtes SQL pour récupérer les commentaires. Disons que ce serait dans ce cas présent, après l'ajout d'1 commentaire, des requêtes inutiles (superflux). Disons qu'il faudrait peut être 2 méthodes coté Billet : Une qui récupère les Commentaires en Bdd qui les rajouterait au Billet, une autre renvoie les Objets Commentaires (getCommentaires()). Faut voir ... Benjamin a peut être un avis ... plus avisé.
__________________
Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20 Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra] |
|
|
|
00
|
|
|
#11 | ||||||||
|
Futur Membre du Club
![]() |
Merci Benjamin,
Dernière chose, si j'utilise le premier appel : Code :
Directement en SQL : Code :
Code :
Code :
|
||||||||
|
00
|
|
|
#12 |
|
Futur Membre du Club
![]() |
|
|
00
|
|
|
#13 | |||||||||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Citation:
La méthode Billet::ajouterCommentaire doit donc soit - appeller Commentaire::creer et récupérer son retour (une instance de Commentaire) pour l'insérer dans sa liste de commentaire (Billet::$_commentaires) - laisser le contrôleur de commentaire insérer en DB (s'il en est capable), là encore, tu peux faire un constructeur avec plusieurs signature comme je l'ai montré plus haut (une signature pour la création et une signature pour la réccupération de données). Histoire de garder ça propre et clair, je te recommande de ne pas abuser des signatures multiples: PHP n'étant pas fait pour à la base, ça devient complexe pour manipuler classes et objets... Voici ce que je te recommande pour la classe Commentaire (on part de l'hypothese que tu dispose d'un singleton Database pour PDO, si tu ne sais pas les faire, je t'en fournirai un, c'est très pratique à utiliser): Code :
Code :
Code :
Code :
Code :
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
|||||||||||
|
00
|
|
|
#14 |
![]() ![]() Michel RottaResponsable d'exploitation informatique Inscription : septembre 2005 Messages : 4 913 ![]() |
Si je peux me permettre d'intervenir, un peu tard dans votre conversation.
Structurellement ce n'est pas à l'objet billet d'ajouter un commentaire, mais à l'objet commentaire de lier un billet. Donc c'est dans l'objet commentaire qu'il faut prévoir une méthode setBillet() avec deux paramètres possibles :
Accessoirement, ce que vous travaillez ici et ce type d'accès est déjà utilisé dans de nombreux ORM, il serait peut-être intéressant d'y jeter un œil avant de réinventer la roue. Je me retire sur la pointe des pieds.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
|
|
00
|
|
|
#15 | ||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 2 984 ![]() |
Pas envie de prendre un ORM, j'aurais l'impression d'annihiler des fourmis à la bombe atomique.
Cela étant, je trouve que Michel Rotta à raison dans un sens: c'est effectivement la table "commentaire" qui porte l'information "id_billet". Dons si on s'en tiens à une stricte modélisation objet, c'est effectivement au commentaire de connaitre son billet... Cependant, je maintiens qu'il est plus pratique d'avoir une classe Billet capable de retrouver ses commentaires (et de les stocker dans sa map au passage), quite à appeller une méthode statique de Commentaire pour ramasser des billet. Est ce que ça serait convenable : Code :
-- EDIT: Edwin on the rock!
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même). Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...". Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug. Les boutons et existent, servez-vous en
|
||
|
00
|
|
|
#16 |
![]() ![]() Michel RottaResponsable d'exploitation informatique Inscription : septembre 2005 Messages : 4 913 ![]() |
Ce n'est que ce que j'ai décris plus haut.
Ton billet peut récupérer par une méthode un objet collection d'objets commentaire (il n'y a pas d'erreur sur les s). Par contre, si tu crées un nouveau commentaire, il convient d'instantier un nouvel objet commentaire, de le compléter y compris avec l'objet billet associé et de le sauvegarder. C'est la seul bonne méthode pour garder une indépendance entre des entités dans ton modèle. Ici tu n'en as que 2, tu peux peut-être jongler un peu, imagine avec une structure plus habituel et entre 50 et 100 tables... Pour ce qui est de tuer des fourmis avec des bombes atomique, j'ai entendu dire qu'elles étaient résistantes aux radiations... ![]() J'en reviens à l'ORM, jette un œil attentif du côté de Doctrine 2, il a une approche très similaire à la tienne et pourrait te faciliter grandement la vie. Même pour deux tables. Justement en ne réinventant pas la roue. Reste a savoir si ton projet est pour apprendre à manipuler les données (et alors ton approche est la bonne) ou a faire un site en exploitation (et alors l'ORM est une option à prendre sérieusement en considération). A partir d'ici la disgression sur les ORM, Framework et patterne continue ici.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
|
|
00
|
Copyright © 2000-2012 - www.developpez.com