|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
![]() ![]() Ingénieur développement logiciels Inscription : mai 2002 Messages : 3 725 ![]() |
Bonjour
Je débute avec le ZF, et je bute déjà sur un éceuil En effet les possibilités d'ORM sont séduisantes mais... c'est absolument nul point de vue requêtes SQL puisque ça fait un SELECT pour chaque table liée, que ce soit en lazy ou full loading. (la différence entre les 2 modes se situe juste au niveau du moment où on exécute les SELECT secondaires)C'est pour moi inacceptable sur une base mysql avec des tables comportant des dizaines de milliers de lignes sur un petit serveur. Je cherche donc le moyen d'optimiser l'ORM basique de ZF en créant mes objets sur base des champs adéquats, que je sélectionnerais au moyen d'une requête SQL propre (et surtout unique Prenons un exemple abstrait, mettons que j'ai 2 tables SQL, t1 et t2. Je crée 2 classes dérivées de Zend_Db_Table_Abstract, et à partir de t1 je voudrais récupérer les informations de la table t2 qui est liée. En SQL je ferais : SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ON t2.id_toto = t1.id_toto Je me vois donc faire une petite fonction genre "myFetch()" dans la classe t1, qui utilise le db adapter pour passer la requête SQL; mais ensuite tout le noeud du problème consiste à lui dire comment transformer le résultat en objets t1 et t2... Je ne sais pas si je suis clair ![]() Y a-t-il une méthode magique pour fabriquer son mapping objet à la main, ou bien il faut créer des classes t1_ovh et t2_ovh en mettant tous les champs t1 et t2 en attributs "protected" et en gérant tout ça à la main ? Un grand d'avance à ceux qui pourront m'aider J'ai cherché au préalable ici et sur google, mais je n'ai pas trouvé de réponse satisfaisante
__________________
Tutoriels sur les UPS, e-commerce, PHP, critiques de livres... Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles. Je n'ai rien à voir avec la société www.ovh.com ! |
|
|
00
|
|
|
#2 |
![]() ![]() Ingénieur développement logiciels Inscription : mai 2002 Messages : 3 725 ![]() |
Grâce à un post de gorgo, il semblerait que la méthode magique soit fetchObject
Enfin ça n'a pas l'air si simple que ça quand il s'agit de séparer différents champs d'un même select dans plusieurs objets différents... ![]() Dans ce cas, c'est peut-être plutôt la fonction bindColumn qu'il faut exécuter, pour faire pointer chaque champ du résultat vers un attribut de la classe ? http://fr.php.net/manual/en/function...bindColumn.php Suis-je dans la bonne direction ?
__________________
Tutoriels sur les UPS, e-commerce, PHP, critiques de livres... Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles. Je n'ai rien à voir avec la société www.ovh.com ! |
|
|
00
|
|
|
#3 |
![]() ![]() Ingénieur développement logiciels Inscription : mai 2002 Messages : 3 725 ![]() |
Bon hé bien je n'étais pas dans la bonne direction
et j'ai trouvé une solution Je ferai une doc un de ces jours pour expliciter cela (après avoir un peu joué avec et voir si ça marche bien pour tous les cas, et aussi optimisé un peu le code)
__________________
Tutoriels sur les UPS, e-commerce, PHP, critiques de livres... Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles. Je n'ai rien à voir avec la société www.ovh.com ! |
|
|
00
|
|
|
#4 |
|
Membre à l'essai
![]() Inscription : août 2007 Messages : 21 ![]() |
Oui, tiens-nous au courant.
Ta solution a l'air intéressante. Moi aussi, je trouve innacceptable la charge induite sur le serveur web par le full loading. C'est une des raisons pour lesquelles je n'utilise pas (encore) l'ORM. Mais avec ta méthode, peut-être... ? |
|
|
00
|
|
|
#5 |
|
Nouveau Membre du Club
![]() Inscription : août 2007 Messages : 95 ![]() |
Bonjour,
Cela fait plusieurs heures que je cherche a faire une jointure entre 2 classes en utilisant l'ORM mais je n'y arrive pas quelqu'un peut me donner un exemple simple sil vous plait ? |
|
|
00
|
|
|
#6 | ||||||||||
![]() ![]() Ingénieur développement logiciels Inscription : mai 2002 Messages : 3 725 ![]() |
OK désolé, je n'ai pas abandonné mais j'ai eu d'autres choses à faire au boulot, mais je m'y réattelle parce que j'ai un projet à terminer pour janvier 2008 donc j'ai intérêt à mettre les bouchées doubles
![]() Alors je vais tenter d'expliquer le principe Avant d'attaquer le code il faut comprendre basiquement le fonctionnement de l'ORM du ZF. Lorsqu'on fait appel aux méthodes findXX(), findParentRow() etc. pour récupérer un objet lié (jointure), le framework effectue une requête SQL, et sur base de l'array du résultat (renvoyé par l'objet Zend_Db), ZF va créer un objet Zend_Db_Table_Rowset contenant un ensemble d'objets Zend_Db_Table_Row pour chaque ligne de résultat. Ceci est expliqué dans l'excellent tuto de Julien. Notre but est de ne plus devoir faire appel aux méthodes findXX(), sans non plus faire du full loading puisque cette dernière méthode ne résoud pas notre problème (effectue autant de requêtes select qu'il y a de jointures, donc très gourmand en ressources). Pour y arriver, nous créerons manuellement notre rowset de résultats. Détails ci-dessous. Considérons pour notre exemple un modèle en 2 tables : Document et Auteur. Pour simplifier, on considérera qu'un document ne peut avoir qu'un seul auteur et un auteur peut avoir plusieurs documents bien sûr, donc la table Document aura une clé étrangère id_auteur pointant sur la table Auteur. Nous allons créer une classe Document de manière classique, donc dérivée de Zend_Db_Table_Abstract. Dans cette classe nous pouvons définir les liens ORM au moyen du tableau $_referenceMap au cas où nous aurions besoin d'utiliser l'ORM de base du framework dans certaines situations. Mais pour faire son ORM personnalisé, ce n'est pas nécessaire. Par contre, ce qui est absolument vital c'est de remplacer la classe résultat par défaut par une que nous allons créer, ce qui se fait en renseignant l'attribut $_rowClass (par défaut = Zend_Db_Table_Row). Code php :
Ensuite dans notre classe Document nous allons créer une fonction pour extraire les résultats qui nous intéressent, appelons-la liste(). Là en considérant que nous construisons la requête SQL dans la variable $sql voici le code intéressant qui va générer les résultats sous forme d'objets : Code php :
Le chargement explicite de la classe n'est pas nécessaire si vous utilisez l'auto-loader de ZF. Illustration : Code php :
Si on veut créer d'autres liaisons, on peut procéder de la même manière, en prenant soin de réinitialiser à chaque fois le tableau $fields. Code php :
Voyons maintenant l'utilisation : Code php :
Voilà j'espère que j'ai été +/- clair ? Dites-moi quoi, que je puisse améliorer s'il le faut, et en faire probablement une Q/R de FAQ ou un mini-article.
__________________
Tutoriels sur les UPS, e-commerce, PHP, critiques de livres... Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles. Je n'ai rien à voir avec la société www.ovh.com ! |
||||||||||
|
|
00
|
|
|
#7 |
|
Nouveau Membre du Club
![]() Inscription : août 2007 Messages : 95 ![]() |
Pour ma part ca me semble assez clair, meme si je suis debutant et que certains procédés m'echappent encore dans le Zend
|
|
|
00
|
|
|
#8 |
![]() ![]() Guillaume RossoliniDirecteur technique Inscription : février 2004 Messages : 13 720 ![]() |
Salut
Je viens de tomber là-dessus, au cas où l'idée t'intéresse : What is new in PHP 5.3 - part 2: late static binding
__________________
Mes articles - Zend Certified Engineer (PHP + Zend Framework) Ressources PHP - Ressources Zend Framework |
|
|
00
|
|
|
#9 |
|
Expert Confirmé
![]() ![]() Urbaniste Inscription : juillet 2004 Messages : 1 428 ![]() |
je viens de regarder ta proposition
il faut la prendre pour l'exemple mais avec des pincettes beau boulot pour décortiquer le principe mais quelques petites réserves attention à la création d'un auteur dans le constructeur du doccument ce constructeur est appelé par diverses méthodes et pas seulement la méthode liste avec sont fetchall il y a là un potentiel problème en effet un find($id) sur ta table va remonter un document sans auteur et ton constructeur n'en tient pas compte. ensuite ton constructeur construit lui même un auteur mais ne l'attache pa à la table auteur mais à la table document donc finalement ça ne peut pas te servir pourquoi ne pas simplement en faite un StdClass object en faire un auteur est intéressant si c'est effectivement un objet auteur complet comme si on l'avait sortit de la table auteur et dans ce cas il convient de l'attacher à la bonne table. enfin il ne faut pas utiliser ton document pour faire un $document->save() car tu vas avoir des pbs avec l'auteur bref tout n'est pas fini et ton post mets l'accent sur l'essentiel. A+JYT |
|
|
00
|
|
|
#10 |
![]() ![]() Ingénieur développement logiciels Inscription : mai 2002 Messages : 3 725 ![]() |
Merci pour ce commentaire très instructif, je vais à regarder à cela de plus près dès que possible
__________________
Tutoriels sur les UPS, e-commerce, PHP, critiques de livres... Ce forum est fait pour vous et surtout par vous, merci d'en respecter les règles. Je n'ai rien à voir avec la société www.ovh.com ! |
|
|
00
|
|
|
#11 |
|
Futur Membre du Club
![]() Inscription : octobre 2007 Messages : 13 ![]() |
Je me pose actuellement les mêmes questions... Pendant mes recherches je suis tombé sur ce post :
http://fashion.hosmoz.net/post/2007/...-relationships Ça a l'aire de bouger du coté de chez Zend aussi : http://www.nabble.com/New-ideas-ques...html#a13756929 http://www.nabble.com/Re%3A--fw-gene...html#a13757451 |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com