Je pense ma question se résume à deux questions:contiguïté Liste modèle avec deux tables
Comment puis-je construire une structure arborescente traversable en PHP lorsque l'arbre est stocké dans MySQL (entre deux tables) en utilisant l'approche du modèle de liste d'adjacence tout en gardant à l'esprit les performances? Qu'est-ce qu'une approche maintenable pour afficher l'arbre dans les formats requis sans dupliquer le code de traversée et jeter la logique avec les instructions if/else et switch?
Voici plus de détails:
J'utilise le Zend Framework.
Je travaille avec un questionnaire. Il est stocké dans une base de données MySQL entre deux tables distinctes: questions et question_groups. Chaque table étend les classes Zend_Db_Table_ * appropriées. La hiérarchie est représentée à l'aide de l'approche du modèle de liste d'adjacence.
Je me rends compte que les problèmes que je rencontre sont probablement dus au fait que je suis en train de bourrer une arborescence dans un SGBDR, donc je suis ouvert aux alternatives. Cependant, je stocke également les répondants au questionnaire et leurs réponses, de sorte que d'autres approches devraient soutenir cela.
Le questionnaire doit être affiché dans différents formats HTML:
- En forme pour la saisie des réponses (Zend_Form)
- Comme une liste ordonnée (imbriquée) avec des questions (et certains groupes) comme liens pour voir les réponses par question ou par groupe.
- Comme une liste ordonnée (imbriquée) avec des réponses ajoutées à chaque question.
Les questions sont des nœuds feuilles et les groupes de questions peuvent contenir d'autres groupes de questions et/ou questions. Combiné, il y a un peu plus de 100 lignes à traiter et à afficher.
Actuellement, j'ai un assistant d'affichage qui effectue tout le traitement en utilisant la récursivité pour récupérer les enfants d'un groupe de questions (une requête qui effectue une union entre les deux tables: QuestionGroup :: getChildren ($ id)). De plus, lors de l'affichage du questionnaire avec la réponse à la question, deux questions supplémentaires sont nécessaires pour récupérer le répondant et sa réponse à chaque question.
Bien que le temps de chargement de la page ne soit pas très long, cette approche est incorrecte. La récursivité et les requêtes de base de données multiples pour presque tous les nœuds ne me rendent pas très chaud et flou à l'intérieur.
J'ai essayé recursion-less et des méthodes récursives sur le tableau d'arbre complet retourné à partir de l'UNION pour construire un tableau hiérarchique à parcourir et à afficher. Cependant, cela semble se briser car il y a des identifiants de nœuds dupliqués du fait que les groupes et les questions sont stockés dans des tables séparées. Peut-être qu'il me manque quelque chose là ...
Actuellement, la logique pour afficher l'arbre dans les formats énumérés ci-dessus est tout à fait un gâchis. Je préférerais ne pas dupliquer la logique de traversée partout. Cependant, les conditions générales partout ne produisent pas non plus le code le plus facilement maintenable.J'ai lu sur les visiteurs, décorateurs et certains des itérateurs PHP SPL mais je ne sais toujours pas comment tout cela fonctionnerait avec les classes qui étendent Zend_Db_Table, Zend_Db_Table_Rowset et Zend_Db_Table_Row. D'autant plus que je n'ai pas résolu le problème précédent de construction de la hiérarchie à partir de la base de données. Ce serait bien d'ajouter facilement de nouveaux formats d'affichage (ou de modifier ceux qui existent déjà).
Merci, Bill. J'ai ajouté une colonne root_id aux deux tables et implémenté les méthodes que vous avez suggérées (http://pastie.org/762955). Je ne suis pas capable de voir la grande image cependant. Comment la méthode d'itération sur les lignes dans le travail de Rowset traitant de l'arbre s'étendrait sur deux tables? Je suppose que fetchTreeByRootId() doit utiliser UNION. Ou créer une vue serait-il une meilleure solution? Bien que j'apprécie de pouvoir utiliser les classes existantes ... – Lauren
Bill, merci d'avoir clarifié. Cela fonctionne magnifiquement. Je travaille toujours sur l'intégration des feuilles (questions) dans le mix. Je posterai ma solution finale une fois que j'aurai terminé. Espérons que cela profitera à quelqu'un d'autre qui pourrait tomber dans le même scénario. – Lauren
Je suis content que ça a marché pour vous. Btw, j'ai changé 'initTree()' ci-dessus pour être une fonction 'public' car elle doit être appelée par la classe Table. Vous avez probablement déjà trouvé la même chose. –