|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||||
|
Invité de passage
![]() |
Bonjour
Oui encore une comme qui dirait, en fait j'ai surtout besoin de vos retours que je sais être pointus pour avoir lu beaucoup par ici. Cette classe a été écrite avec pour but de me simplifier la vie lorsqu'il me fallait faire appel a la bdd pour demander une requete select et a chaque fois subir le while etc de pdo. J'ai donc créé cette petite classe, avec mes compétences limitées (à savoir surtout, non professionnelles) qui évolue au fur et a mesure de mes besoins, pour l'instant elle ne supporte que les select, mais vu la vitesse d'avancement de mon projet je la rallongerai bien sur pour supporter les create update et autres joyeusetés. Son fonctionnement est simple. C'est un singleton, et les appels a ses fonctions sont clairs. La méthode d'appel permet surtout d'éviter les erreurs de syntaxe puisque c'est la fonction qui recrée la requete sql en fonction du tableau contenant les différents arguments du select. Elle parse ensuite la ressource obtenue et la renvoit sous forme de tableau. Plutot que des grands discours : Code :
Son utilisation se fait ainsi : Code :
Si on sait qu'on a plusieurs résultats : Code :
Dans cette utilisation $this->config vaut au minimum Code :
A savoir que je l'utilise couplée à une libraire de mise en cache faite maison si ca en intéresse certains... J'attends vos avis constructifs ! |
||||||||
|
|
00
|
|
|
#2 |
![]() ![]() |
Salut,
j'ai parcouru rapidement ta classe et voici mon avis : l'approche retenue ne me semble pas bonne : cette classe a trop de responsabilités : tu mélanges un peu tout : connexion, exécution, construction de la ressource. Et bizarrement ta classe n'offre aucune sécurité quant à l'injection des données en provenance de l'utilisateur. Tu devrais au moins préparer ta ressource et ensuite seulement l'exécuter. Bref, je t'invite à bouquiner un peu les subtilités de PDO. Tu trouveras sur le net des tas et des tas de classes offrant ce genre de service : prend le temps de les décortiquer et inspire-toi en. Bonne continuation.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
|
00
|
|
|
#3 |
|
Invité de passage
![]() |
Bonsoir,
Merci de ta réponse rapide. Maintenant concernant les responsabilités de cette classe, je dois avouer qu'il s'agit là d'une logique qui m'échappe, que celle qui serait de compartimenter entre plusieurs classes, ce qu'une seule peut réunir. Je m'explique. Mon but pour cette classe a justement été de réunir tous mes besoins quant à la bdd, donc en fait la connexion à pdo, et les executions de requetes via des appels simplifiés (ou au moins clarifiés). Je voulais justement que cette classe de gestion soit le plus possible "autonome", et que sa finalité soit pour le code qu'il l'utilise autour, une magnifique simplification de l'utilisation de pdo qui m'a parue, à l'instar de mysql_ a son époque, peu claire pour le néophyte, et franchement chiante à utiliser dans le code de tous les jours. C'est la raison pour laquelle elle fait tout, connexion, soumission des requetes, parsing des ressources, pour renvoyer des données le plus simple d'accès possible. Voilà en gros ma vision des choses, qui je le concède est peut être erronée aux yeux de codeurs avec plus d'expériences. Mais dans ce cas, j'aimerais qu'on me partage cette vision des choses de la même façon que je l'ai faite. Je ne demande qu'à comprendre Pour la sécurité, my bad je l'ai pas ajoutée, vu que pour l'instant elle fonctionne seulement en local je n'ai pas encore songé à l'intégrer, mais je devrais le faire c'est vrai. Mais c'est plus quelque chose que j'imaginais intégrer à l'extérieur, donc aux appels des requetes, comme je le fais déjà pour la définition du mode et de la page, des id possibles etc. Chacun est controlé via une liste prédéfinie dans la config, il n'y a que certains noms de pages autorisées, tout autre nom renvoyant à la page d'erreur. Il n'ya que certains mode autorisés (lire ecrire editer), tout autre renvoyant au mode par défaut (donc lire ou présentation générale du contenu de cette page). Et quand est id est passé, il est traité avec intval() auparavant. De cette manière je sais que quelque soit la requete passée a la classe, aucune ne peut contenir d'injection. N-T-U-I :p Pour la préparation des requetes suivies de execute, j'avais imaginé à la base pour mon code, et mon moteur de contenu, de ....comment dire, "prévoir", quelles ressources seront nécessaires à l'affichage de la page, et donc in fine quelles requetes seront nécessaires. De cette façon le moteur de contenu aurait pu balancer ces requetes à PDO avec prepare, et le moment venu à l'affichage du template final, récupérer les données d'un coup avec execute() pour les remplacer dans le template. J'ai finalement opté pour la solution que j'utilise actuellement, les requetes directes à la volée selon les besoins, combiné avec un systeme de cache qui fonctionne assez simplement, en stockant l'array renvoyé par cette classe dans un fichier avec serialize et un nom passé en argument au système de cache (appelé avec cacheThis($namefile, $data) et getCache($namefile)). Je suis passé à PDO assez récemment (disons 2 mois), et j'ai vite fait le tour de ses possibilités dès le départ, je ne la maitrise pas dans le sens ou j'en connais les plus fines subtilités, mais je pense en avoir saisi les possibilités générales. Il s'agit simplement de ce dont je jasais dans le début de ce post, à savoir une vision des choses différentes entre nous. Différend que je pense, je gagnerai beaucoup a me voir expliqué arguments à l'appui. Je ne demande qu'à apprendre, et ton post est déjà pour moi, par les questions qu'il me fait me poser, un autre pas vers un meilleur code. Si quelqu'un, ou toi-même peut donc m'éclairer, je vous en prie, faites ^^ EDIT : j'oubliais un élement auquel je voulais réagir. J'ai suivi tes conseils et me suis penché sur les autres classes similaires de ci de la sur le web. Bien souvent en effet le seul but de la classe est d'ouvrir/maintenir la connexion, et cela est bien souvent réalisé comme la mienne via singleton. Mais je n'arrive pas à comprendre l'usage "limité" de ces classes. Certaines héritent PDO, ce qui est aussi un concept intéressant mais alors elles deviennent comme la mienne, complétant les fonctions intrinsèques de cette librairie par leurs propres ajouts, leurs simplifications de syntaxe. |
|
|
00
|
|
|
#4 | ||
![]() ![]() |
Salut,
Si ton objectif c'est de faire une classe utilitaire, il faut qu'elle soit vraiment utile or ton code est trop simplifié pour qu'elle le soit. Je m'explique : - vu qu'elle est basée sur PDO qui est déjà une abstraction de l'accès aux bases de données, ta connexion doit au moins offrir les même possibilités que PDO. Or dans ton cas de figure ce n'est pas le cas. La gestion de la connexion devrait être séparée de manière par exemple à les regrouper en pool et offrir un paramétrage exhaustif à l'ouverture de connexion donc pour moi tu devrais créer une classe Connection. Chaque connexion devrait avoir un identifiant unique de manière à pouvoir la solliciter au besoin. - ensuite dis toi bien que créer un SELECT est différent d'un INSERT ou d'un UPDATE et je ne te parle même pas d'une procédure stockée... C'est encore un métier à part : tes ressources ainsi que leur assemblage devraient être gérées individuellement. Dans ce sens tu peux aussi descendre d'un cran au niveau des clauses qui sont factorisables : par exemple un WHERE sera géré de la même manière pour un SELECT ou un UPDATE... - enfin en ce qui concerne l'exécution, c'est un métier à part : cette classe devra faire le lien entre la connexion, la ressource et le résultat de l'exécution. Ne pas mélanger les les torchons et les serviettes est une règle d'or en POO. Tu débutes, c'est normal de ne pas isoler correctement les métiers mais n'oublie pas de peser le pour et le contre de chaque option retenue. Voici une idée d'ébauche : Code :
Allez bon courage.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
||
|
00
|
|
|
#5 |
|
Invité de passage
![]() |
Bonjour,
Ok je comprends bien mieux maintenant. Le but est donc de diviser les différentes étapes et fonctions pour les spécialiser un maximum. Au final il est vrai qu'il est encore plus facile pour le code environnant de se voir simplifiés les appels si tout cela est bien construit. Pas besoin de tableau je vois déjà la structure du code que je vais devoir mettre en place ^^ Je vais suivre ta structure globale, et factoriser les clauses communes entre types de requetes est une excellent idée. Merci de ces infos, je devrais vous revenir prochainement |
|
|
00
|
|
|
#6 |
|
Membre habitué
![]() Étudiant Inscription : juin 2008 Messages : 79 ![]() |
Si tu veux sur-coucher PDO, renseigne-toi sur ce qui a déjà été fait, je prendrai 2 exemples qui sont Zend_Db et Doctrine.
Beaucoup de design-patterns existent pour répondre aux problèmes de conception de l'abstraction des données.
L'implémentation proposée par rawsrc est intéressante mais j'ai du mal à percevoir l'apport de la séparation des type de requêtes sous forme de classes (ce sont des string builder ?), surtout si en plus il y a une méthode distincte pour chaque type dans la classe Engine, annulant de fait l'intérêt que pourrait avoir une classe abstraite Ressource. De même la classe statique Engine me pose problème car elle implémente des méthodes pouvant être spécifiques à certains type de SGBD, hors ici aucune distinction n'est possible et une classe statique n'aide pas à l'injection ou au découplage... Une petite remarque en passant : Le nommage des classes, à mon avis, mériterait d'être plus explicite, un SELECT est un type de requête et non une ressource, la ressource serait à la limite l'objet de connexion. «Engine» n'est pas très explicite, Moteur de quoi? Je ne sais pas si «Engine::select()» est très parlant dans un code source... Si l'on regarde ce qui à été fait dans la majorité des ORM web, on voit que les méthodes de la classe Engine sont plutôt présente au niveau des classes de type Adaptateur et c'est plutôt la construction de la requête SQL (au sens large) qui se voit encapsulée dans une classe à part. Je mets en pièce jointe un squelette (très) simplifié d'une implémentation à la Zend_Db, si ça peu aider. Il manque pas mal de chose mais pour une première approche, l'essentielle me paraît là, au moins pour la compréhension. Pour info, le composant Zend_Db(1.12) est utilisable de manière indépendante. à bon entendeur, Salut! |
|
00
|
|
|
#7 |
|
Invité de passage
![]() |
Merci pour le fichier joint, j'ai regardé ca avec intérêt
Il m'a fallu un peu de temps pour distinguer le cheminement de la logique de cette organisation. Codant de facon assez basique j'ai du creuser dans mes souvenir pour me rappeler des interfaces Apres, ca reste pour moi une influence, ou dirais-je un enrichissement. C'est très intéressant de voir comment d'autres systèmes fonctionnent, mais malgré l'adage qui voudrait qu'on ne réinvente pas sans cesse la roue, moi j'ai mon adage-réponse qui dit qu'on maitrise mieux sa propre roue que celle des autres ![]() Je n'ai pas encore commencé la réécriture du moteur sql que j'utilise, me focalisant pour l'instant sur le moteur de contenu qui me prend pas mal de temps et d'énergie. Par contre je vois déjà ce que je veux au final pour cette classe, grace a tes explications et celles de rawsrc, comme la classe de construction de requête à la volée, la gestion de plusieurs connexions, la manipulation des ressources. A propos de cette dernière fonctionnalité, j'en connais une implémentation dans le code de Dotclear Pour le multiSGBD, j'hésite bcp pour la bonne raison que je me suis pas mal renseigné pour le choix a faire dans l'optique d'un gros projet. SourceForge utilisaient il y a peu encore MySQL et ont du switcher sur PostGreSQL pour voir un gros boost de leurs performances, leur BDD mettant à genoux le serveur avec mysql. Depuis les choses ont bien changées et il semblerait que les gains en perf de MySQL le rendent un peu plus compétitifs. Je vais donc me focaliser sur lui. Je mettrais la classe à jour lorsque le moment sera venu. Merci encore pour ce retour d'experience. |
|
|
00
|
|
|
#8 | |
![]() ![]() |
Bonjour,
Citation:
Bref, tu te rapproches du fonctionnement par procédures stockées tout en conservant la souplesse de faire du SQL. Je te l'accorde le nommage aurait pu être mieux trouvé : Statement à la place de Resource. Une dernière chose, ne me parle pas d'injection de quoi que ce soit au niveau du moteur de la base de données. Il ne faut pas tout mélanger : utiliser un framework d'injection pour pouvoir utiliser sa base de données est une ineptie. Faut vraiment arrêter avec cette mode de vouloir tout injecter : une base de données fait partie des fondations de n'importe quel développement et avoir un lien raisonnablement fort entre elle et le code n'est pas si problématique.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
|
|
00
|
|
|
#9 |
|
Membre habitué
![]() Étudiant Inscription : juin 2008 Messages : 79 ![]() |
Oui oui, concernant l'injection, je parlais des classes statiques en général, d'éviter d'en faire quand on le peu (de même pour les Singleton en passant
Mais bien sûr que parlez ici d'injection pour un simple accès à son SGBD n'a pas d’intérêt. Par contre je ne suis pas tout à fait d'accord pour le lien fort entre la persistance et le domaine métier, je trouve, quand c'est possible (et quand la taille du projet le justifie un minimum) que le découplage (avec l'IoC ou non) est vraiment le bienvenue. Ce n'est pas pour rien que Doctrine a abandonné ActiveRecord pour utiliser DataMapper. |
|
00
|
|
|
#10 | ||||
|
Invité de passage
![]() |
J'utilise un singleton pour avoir accès à l'objet zSql dans tous les objets créés par l'objet principal. Au début je passais carrément l'objet principal à l'objet créé (- $instance = new objet($this) -), et le pattern singleton permet de se passer de cette disgrace.
Je ne maitrise pas assez le php pour m'affranchir de cette limitation. Je sais lire et comprendre du php supérieur à mon niveau personnel, mais coder à ce niveau j'ai beaucoup de mal je me sens tout perdu. Par exemple votre discussion actuelle je suis largué parce que je ne connais pas les conséquences des termes sur le code qui en résulte. Il m'a fallu consulter ca : http://fr.wikipedia.org/wiki/Inversion_de_contr%C3%B4le http://fr.wikipedia.org/wiki/Injecti...C3%A9pendances http://code.anonymation.com/zend-fra...d-application/ Pour comprendre un peu ou vous vouliez en venir. Le dernier article est d'ailleurs très intéressant. Je me rends compte qu'en fait ce que je faisais au début, en passant $this a mon objet, bah ca s'appelle techniquement de l'injection par constructeur. Seulement vu que $this dans mon cas contient une variable $this->content dont la taille peut faire plusieurs ko, j'imagine meme pas le massacre sur le serveur. J'ai personnellement toujours fait le voeu de coder léger, et même pour mon CMS (qui me sert en fait a l'élaboration d'une plate-forme participative, pour être prolixe) je dois dire qu'avoir recours a ces framework m'effraie au plus haut point. Ma peur première étant l'inconnu évidemment. Je n'exclue pas un jour de m'y mettre, mais pour l'instant je préfère grandement m'inspirer du concept de ces framework pour faconner le visage de mon code. Pour info en gros, la structure de mon code est la suivante : index.php - inclut les classes - instance l'objet principal - affiche la variable $objetprincipal->template; l'objet principal lui a cette forme exacte (je vous passe les attributs) Code :
Les coreBoxes sont partie intégrante du coeur du CMS et font l'objet d'une seule classe. Les craftedBoxes sont des contenus dynamiques reliés à la BDD, avec un mini-template (item) propre qui est modifé selon les infos de la BDD. Une classe seule les gère en fonction de leur config : Code :
Enfin les complexBoxes sont des contenus particuliers, qui en plus de pouvoir utiliser tous les autres contenus pour se construire, ont leur fonctionnement propre, car étant l'objet d'une classe qui est propre à chaque complexBox (par exemple le forum est codé dans la classe buildForum extends complexBox). A noter qu'il ya une gestion sommaire des "hooks" pour chaque contenu. Bref, vous voyez ici un aperçu de mon niveau, hautement critiquable je n'en doute pas, mais qui je pense est exploité a son maximum dans ce CMS. C'est pourquoi venir ici, vous lire, recevoir vos critiques et vos apprentissages, est pour moi quelque chose de très intéressant, parce qu'il me permet de faire évoluer ce niveau. Mais comme je le disais : j'aime ma roue mieux que celle des autres. Du coup ce qui existe me sert d'inspiration plus que de support direct à mon code. ...bon j'ai écrit tout ca et j'appréhende ce que vous en pensez... |
||||
|
|
00
|
Copyright © 2000-2013 - www.developpez.com