CLASS ABSTRACTION MYSQL (ORM)

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 9 août 2008 à 20:24
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 - 17 août 2008 à 13:27
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/47554-class-abstraction-mysql-orm

neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
17 août 2008 à 13:27
C'est quand même dommage de ne pas s'inquiéter de l'interopérabilité quand on utilise PDO...
Si tu utilises PDO, tu devrais t'en inquiéter tout de suite, sans forcément l'implémenter... Mais l'avoir en tête et en tenir compte dans ce qu'on fait, ça me parait important...
mytrip Messages postés 5 Date d'inscription samedi 9 août 2008 Statut Membre Dernière intervention 16 août 2008
16 août 2008 à 18:53
salut :)
pour les procédures stockées ça pourrait faire l'affaire, mais j'aime bien faire des petit "datagrid", avec des trie par nom etc ...
donc dans ces là, je génère les requête automatiquement selon le besoin, ça deviens plus difficile de faire ça avec des procédures stockés... peut être qu'il y'a des solutions, mais je ne les connais pas.
cette class me permet d'avoir un bon contrôle sur ce qui est généré.

je préfère recodé une class si je change de db, plutot que de codé une class qui fait tout.
il suffirais de charger la bonne class selon le driver, mais l'interoperabilité c'est pas mon soucis pour le moment :)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
13 août 2008 à 11:25
Salut,

Si tu as souvent la même requête à quelques variables près (comme le nom de la table), pourquoi ne pas utiliser une procédure stockée ?

Concernant la clause particulière LIMIT, je m'étais posé la question à un moment. J'en avais parlé avec Malalam, qui m'avait dit qu'on pouvait tout à fait récupérer tous les enregistrements et utiliser un itérateur (un LimitIterator plus exactement) pour n'accéder qu'aux résultats souhaités.
Une alternative à LIMIT existe, utilisant des variables existe (je ne l'ai pas en tête) et doit se retrouver sur le net grâce à notre ami à tous.

Sinon, toujours dans un soucis de compatibilité de code, il me semble (mais je dis peut-être une bêtise, j'ai commencé seulement hier à me pencher dessus pour mes besoins personnels) que le DSN n'est pas formé de la même manière suivant les SGBDR... Par exemple, et d'après la doc de PHP, un DSN MySQL ressemble à ça :
mysql:host=localhost;port=3306;dbname=mydatabase
on passe alors user et password en argument du constructeur.
Pour PostgreSQL, le DSN ressemble à ça :
pgsql:host=localhost port=5432 dbname=mydatabase user=myself password=topsecret

Rien que pour séparer les "arguments" du DSN, MySQL utilise des points-virgules et pgSQL utilise des espaces.
Et je ne prends que ces deux exemples là... On peut aussi se connecter à MySQL via un socket Unix. On peut se connecter à une base de données Access (beurk, oui, je sais) en utilisant un nom catalogué, ou un DSN plus "classique".
Je manque de pratique de ce côté là pour pouvoir en parler plus en détails.

Je continue de penser que ta classe apporte une surcouche pas vraiment nécessaire, si ce n'est qu'elle peut éventuellement gérer des incompatibilités de code d'un SGBDR à l'autre, et permettre aux requêtes de fonctionner dans tous les cas. Mais ça représente un gros gros boulot... Et je trouve dommage d'avoir à développer une classe spécifique pour gérer chaque SGBDR, alors que PDO est supposé servir à ça... Il y a peut-être encore des progères à faire du côté de PDO...

Cela dit, tu sembles accorder à cette classe une véritable importance didactique, et ça, c'est très très bien.
mytrip Messages postés 5 Date d'inscription samedi 9 août 2008 Statut Membre Dernière intervention 16 août 2008
13 août 2008 à 00:21
tout a fait d'accord pour les exeptions

pour le coté "sql compliant", je pense que je devrais utiliser une class interface et une class implement pour le type de db.
et, par exemple, recoder le comportement de la fonction limit selon le type de db si besoin dans la class implement.

ce qui m'a fait coder ça, c'est que j'ai souvent les mêmes codes avec des tables au nom différent.
déclarer des variable gobale ou des constante avec le nom des table ne me plaisais pas.
"SELECT ".MA_TABLE.".bla, ".MA_TABLE.".bli" ...
ça deviens vite galère

pour les transactions ça doit passer, puisque ce n'est qu'un extension de pdo.
je n'ai pas encore testé mais c'était dans mon intention de les utiliser :)

cette classe n'est qu'un ensemble de méthode pour contruire des requêtes (avec des lacune certes) et utilise les méthodes pdo pour le reste.
La plus grosse lacune de cette source a mes yeux, c'est de ne pas gérer les jointures (sauf en passant les requêtes directement biensur).
je n'ai pas trouver de solution pour le moment ... et je me demande bien comment je pourrais faire :/
j'en suis encore au stade expérimentale avec cette source, je l'utilise sur un petit projet test. j'aimerais bien la développer un peu plus sans en faire une énorme usine a gaz (c'est déjà pas mal tordu comme ça là).

en tout cas merci d'avoir pris le temps de regarder la source et de l'avoir commenté ;)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
12 août 2008 à 20:41
Mea culpa, j'ai très mal lu :-)
Donc oublie ces commentaires.
Par contre, maintenant que j'ai lu le contenu du zip (en partie), je suis comme Neige, je comprends quand même mal l'intérêt : simplement parce que je trouve ça bcp plus complexe à utiliser que directement utiliser pdo par exemple. Et surtout, ce que je reproche à tous les packages de e genre (donc pas que le tien :-) : les requêtes deviennent illisibles. Je préfère nettement voir directement un truc du genre
$sQuery = <<<sql
SELECT
t1.bla, t2.bli
FROM
table1 t1
INNER JOIN table2 t2 ON t2.t1_id = t1.t1_id
WHERE
t1.t1_where = :sWhere
sql;
avec un bindValue() qui va bien, plutôt que passer par des méthodes pour faire chaque condition de ma clause WHERE par exemple, et la table de ma clause FROM etc...
C'est quand même plus lisible comme ça.
Maintenant, tu me diras, on n'est pas obligé de pousser jusque là avec ta classe. Certes.

Pour surrenchérir à ce que dit Neige, en effet, fais attention au côté "sql compliant" : LIMIT n'est PAS une clause standard. Et quand elle existe pour un moteur DB, elle ne s'utilise pas forcément comme celle de mysql.
Gaffe aussi au driver PDO choisi par l'utilisateur, tu risques d'avoir des surprises...et dans ce sens, ça manque d'exceptions ton truc.

Au final, ça n'est qu'une surcouche de trucs basiques. Tant qu'à réécrire PDOn autant proposer des trucs inédits et plus complexes : gestion poussée des jeux de résultats multiples (poussée car PDO le fait déjà), des trucs sur les tables systèmes facilitant la récupération des types d'un champ ? Insertion/Update avec vérification du types des champs touchés, etc etc...
Manque aussi la gestion des transactions (c'est basique, mais là, ça manque...!), des procédures stockées (ça rejoint svt les jeux de résultats multiples), etc...

Sinon y a de l'idée pour le code :-) A quelques exceptions près (les exceptions notamment, donc, gestion d'erreur poussée).
mytrip Messages postés 5 Date d'inscription samedi 9 août 2008 Statut Membre Dernière intervention 16 août 2008
11 août 2008 à 23:10
je ne comprend pas bien ?

l'exemple afficher est une class qui utilise cette class !
et ce n'est pas la class elle même qui est affiché :)

il y'a afficher ici:
- un cas avec une class effectivement spécialisé pour un module de news,
- et l'autre qui montre la possibilité de faire des requêtes directement.

ma class je l'utilise dans mon petit framework a ma sauce a moi :)
je m'attendais a plein d'autre remarque, je pense que tu as mal regardé ;)
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
11 août 2008 à 21:56
Hello,

je passe pas svt ces temps-ci, mais bon, rapide ce soir : ouais, mais non...tu fais une grossière erreur : tu obliges l'utilisateur a avoir le même nommage que toi. Et je ne trouve pas ton nommage très bon, qui plus est.
Et la même structure en plus...non, ton code est trop ciblé...et ciblé sur toi uniquement, et encore, juste sur UN exemple de table que tu as dû monter un jour.
Si tu veux faire de la surcouche, pense abstraction, là, tu fais du concret inutilisable pour 99% des gens. Cette classe ne servira jamais qu'à toi.
mytrip Messages postés 5 Date d'inscription samedi 9 août 2008 Statut Membre Dernière intervention 16 août 2008
10 août 2008 à 15:34
ça sert a simplifier l'utilisation des tables d'une bdd
- en faisant abstraction de son nom réelle dans le code
- ça génère des requete proprement
- couplé au requête préparé de pdo aucun risque d'injection sql
- garder un code claire (ça c'est subjectif)
- toute les configuration des tables sont stockées dans un dossier, il est facile de créer un système d'installation pour un petit cms ...

je pense pas que se soit vraiment utile à quelqun qui souhaite débuter, c'est un concept ...
il y'a des chose plus poussée comme propel http://propel.phpdb.org/trac/

mais c'était bien trop lourd pour moi :)
cs_metis15 Messages postés 314 Date d'inscription lundi 19 mai 2003 Statut Membre Dernière intervention 30 novembre 2023
10 août 2008 à 15:16
Yo !! Génial ! ...et pour ceux qui essayent de comprendre un peu PHP/MySQL, peut-on avoir une idée de ce à quoi celà peut servir car là, c'est du chinois.
Une petite application concrète peut-être..? (;o))))
mytrip Messages postés 5 Date d'inscription samedi 9 août 2008 Statut Membre Dernière intervention 16 août 2008
9 août 2008 à 21:19
l'interet n'est pas l'abstraction au type de db, c'est plutôt abstraction de la syntaxe des requétes.
j'utilise pdo, mais je n'aime pas, par exemple, fetch(PDO::FETCH_ASSOC), j'ai donc étendu la classe pdo pour avoir fetchAssoc().
Le choix de pdo,c'est pour les requetes préparée tout simplement :)
et le jour ou j'ai vraiment besoin de changer de bdd, je peut toujours réecrire ma fonction limit().. mais j'avoue c'était pas mon soucis :)

je n'aimais pas non plus avoir le nom de mes table en dur dans les requêtes a l'intérieur, et les truc genre:
select pwet_table.row1, pwet_table.row2 ...

je me suis dit que ça serais bien d'avoir un identifiant pour la table et que le nom réelle de la table soit précisé indépendamment.
donc je déclare un table, et cette table je peut y faire des select, insert, update sans me soucier de son nom, et la requêtes s'écris proprement toute seul.

l'idée de départ c'est un peut ça:
// on déclare la table
$this->Table = new Sql('module.news');

// on créer un objet pour une requête select
$select = $this->Table->select('id,user,sujet,texte,categorie');
// on ajoute une clause where ( on peut encore en ajouter )
$select->where('id',':where','=');
// une clause limit
$select->limit($begin,$end);

qui génère ça:
SELECT test_news.id,test_news.user,test_news.sujet,test_news.texte,test_news.categorie FROM test_news WHERE ( test_news.id=:where ) LIMIT 0,10

le nom de la table peut changer, il suffit de modifier le fichier de config, la requete est propre et le code claire.

mais cette source est loin d'être parfaite, je le reconnais, elle ne fait pas tout ;)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
9 août 2008 à 20:24
Salut,

Quand j'ai vu le titre de la source, je me suis dit : "Mais pourquoi encore faire de l'abstraction, au lieu d'utiliser PDO ?".
Bon, tu utilsies PDO, donc bon...

Alors j'ai vaguement regardé, et j'ai pas bien compris...
Je vois que t'as des classes qui s'appellent SqlMysqlDelete, par exemple... Et là, je ne comprends pas l'intérêt d'utiliser PDO, si c'est pour faire des classes pour du MySQL...
Notamment, tu utilises la clause LIMIT, qui est spécifique à MySQL... C'est con, parce que PDO ne sert plus à rien, là... Autant utiliser MySQLi, ça suffit largement...

Bref, j'ai du mal à vraiment comprendre l'intérêt de ta source...
Rejoignez-nous