[migration] question code pdo_biblio_init

Problèmes, bugs et difficultés rencontrés sur le site.
Avatar du membre
sly
Messages : 5041
Enregistré le : 29 févr. 2004, 17:59
Localisation : Chambéry - Savoie

[migration] question code pdo_biblio_init

Message par sly »

function pdo_biblio_init( $pdo )

A quoi est-elle destinée et quel est son avenir ?
Elle est executée à chaque chargement de fonctions_bdd.php (donc à chaque page du site)
son avenir est-il de contenir toutes les requêtes du site et de les "préparer" pour chaque page ? est-ce en réflexion ?
N'est il pas plus pertinent quand même de rester économe et ne préparer ou exectuer que celles dont on a besoin ?

Est-ce une volonté d'objectif de dire : toutes les requêtes SQL dans un seul fichier ?
Modifié en dernier par sly le 18 févr. 2013, 13:34, modifié 1 fois.
Avatar du membre
yip
Messages : 387
Enregistré le : 08 mars 2004, 23:32

Message par yip »

en gros quand j'ai vu 5 requetes a peu pres identique a plusieurs points du code, j'ai fait comme ils disaient dans le manuel PHP: PDO->prepare.

par exemple dans les news, la faut modifier le UNIXTIMESTAP() qui n'est pas reconnu en PGsql,
on a donc a modifier qu'a 1 endroit au lieu de 5.
Il y a plein de bouts de SQL qui se ressemblent partout, parfois dans des pages insoupconees ...
C'est aussi assez agreable a coder: comme utiliser une fonction au lieu d'ecrire du code PHP, avec les erreurs que ca evite.

On va pas bien sur tout mettre dedans, vu que la variable est trimballée partout, et ca ce sera peut etre pour les VIEWS de PGSQL.
perso, j'en voyais peutre une dizaine, bien séléctionnées, pas forcement celles-la que j'ai mises d'ailleurs ;), mais c'est paeut etre pas l'avenir.
Ce qui est sur c'est que c'est pas plus econome d'avoir des dizaines de requetes identiques partout, avec dans chacune, des quote, des type_mismatch et des timestamp a modifier pour le passage en PG. Pas bon pour la fiabilité du code ca.


inconvenient:
- Effectivement il est lu tout le temps, comme la $pdo qui est global (on peut faire autrement ?)
- Le SQL, pour etre generique, n'est pas optimisé (utilisation abusive du CASE car c'est portable entre PG et MY)
-Selon la doc, il y a un gain a l'execution a partir d'un certain repetitif. mais plus dur qu'on croit de choisir les bonnes requetes !

Bref, si tu vois une autre solution, on vire. Ca facilite meme sa propre suppression ce système ;)
Un cours sur les Views PG SQL ? :avocat:
Avatar du membre
sly
Messages : 5041
Enregistré le : 29 févr. 2004, 17:59
Localisation : Chambéry - Savoie

Message par sly »

yip a écrit :en gros quand j'ai vu 5 requetes a peu pres identique a plusieurs points du code, j'ai fait comme ils disaient dans le manuel PHP: PDO->prepare.

par exemple dans les news, la faut modifier le UNIXTIMESTAP() qui n'est pas reconnu en PGsql,
on a donc a modifier qu'a 1 endroit au lieu de 5.
Il y a plein de bouts de SQL qui se ressemblent partout, parfois dans des pages insoupconees ...
La raison me saute au nez ;-) La gestion des commentaires est ce que je n'ai pas fini de convertir totalement en fonction+objet contrairement aux polygones et aux points.
Mais la solution est peut-être simplement de factoriser la gestion des commentaires dans des fonctions.

L'idée d'avoir : "du code php à un endroit pour manipuler des commentaire et des requêtes génériques pour les commentaires à un autre" ne me paraît pas idéal. je préfère regrouper par thème : "tout ce qui touche aux commentaires" plutôt que par logique technique : "tous ce qui touche au sql"
Mais pourquoi pas laisser pour l'instant, c'est à l'usage qu'on verra ce que ça nous gagne comme temps.
Mais je vois tout de suite que :

Code : Tout sélectionner

	$pdo->requetes->liste_comments->bindValue('comment', -1 , PDO::PARAM_INT ); // -1 = tous
	$pdo->requetes->liste_comments->bindValue('point', -1 , PDO::PARAM_INT ); // -1 = tous
	$pdo->requetes->liste_comments->bindValue('vignette', $vignette ? $vignette : -1 , PDO::PARAM_INT ); // 1 avec, -1 tous , 0 sans
	$pdo->requetes->liste_comments->bindValue('limite', $nombre, PDO::PARAM_INT); //ATTENTION LIMIT attent un INT, ce qui fait foirer la methode array
C'est tout simplement inbitable pour moi. Et je ne parle pas tant de passer des paramètres à une fonction, ça ok, mais de devoir préciser le type : PDO::PARAM_INT, d'avoir une maxi ligne à rallonge et d'être obligé de coller un commentaire tellement c'est pas clair. php dispose déjà de variables, genre :
"select * from commentaires where $vignette and x=7"
à quoi bon refaire un abstracteur de variable à la sauce PDO ? :
"select * from commentaires where :vignette and x=7"

Je ne demande qu'a comprendre l'avantage, mais je reste sceptique (comme toujours ;-) )
C'est aussi assez agreable a coder: comme utiliser une fonction au lieu d'ecrire du code PHP, avec les erreurs que ca evite.
Je préfère vraiment éviter de mettre du code coté SQL.
1) c'est non ou très mal portable
2) le code se retrouve partagé entre des "case" des "if" des "for" coté sql et coté php
3) conceptuellement, sql c'est pour moi la zone de stockage, et des requêtes relationnelles avec index si on commence à y mettre des boucles, on va tout faire ramer sans s'en rendre compte
4) on commence par des if et dans 6 mois on aura des procédures stoquées en pl / pgsql ;-)
inconvenient:
- Effectivement il est lu tout le temps, comme la $pdo qui est global (on peut faire autrement ?)
A la limite, c'est pas un gros problème (si le prépare n'est pas un truc de ouf qui prépare on ne sait quoi)
- Le SQL, pour etre generique, n'est pas optimisé (utilisation abusive du CASE car c'est portable entre PG et MY)
Excellentes raisons d'être méfiant.
Bref, si tu vois une autre solution, on vire. Ca facilite meme sa propre suppression ce système ;)
Laisse pour l'instant, c'est à l'usage qu'on verra
Un cours sur les Views PG SQL ? :avocat:
J'y connais pas grand chose, mais ça ne sert à pas grand chose. Mieux vaut bien concevoir ses requêtes.
Avatar du membre
yip
Messages : 387
Enregistré le : 08 mars 2004, 23:32

Message par yip »

sly a écrit : Mais la solution est peut-être simplement de factoriser la gestion des commentaires dans des fonctions
C'est quoi factoriser ?
sly a écrit : "select * from commentaires where $vignette and x=7"
à quoi bon refaire un abstracteur de variable à la sauce PDO ? :
"select * from commentaires where :vignette and x=7"
raison: centraliser.
ce bout SQL est le meme partout.
jusqu'a present, le "x=7" etait parfois "x='7' ", ce qui etait transparent chez My,et ne passera pas chez PG, pareil pour la solidité de l'argument $vignette, aléatoire.
Par exemple, un bon paquet de variable numerique sont déclarées "$config = '5' ;" ce qui fera foirer PGSQL et passait MY.
donc toutes les modifs a faire partout, tu vois le topo, pour une requete identique.
sly a écrit : PDO::PARAM_INT
raison: standardiser.
une seule ligne aurait suffit mais
PDO, est assez mal foutu. ici, il CAST tout en String.
MySQL s'en fout, PG non. donc en anticipation j'ai été obligé de taper la version longue.
Effectivement, la seule solution est de ne pas faire de pdo->prepare .

Désolé de pas avoir commenté correctement. à un moment, voyant l'ampleur de la tache, j'ai beaucoup codé et peu commenté, pensant y revenir plus tard. ce qu'il faut pas faire.
sly a écrit : Je préfère vraiment éviter de mettre du code coté SQL.
1) c'est non ou très mal portable
quasiment toutes les requetes que j'ai du modifier pour passer en PDO, c-a-d toutes les requetes de toutes les pages, je les ai faites en SQL STANDARD My et PG. si il y a des subquerys, des CASE imbriqués dans des subquery, ca ne veut pas dire que ce n'est pas standard. S'il y a des fonction, comme "NOW()", j'ai vérifié a chaque fois qu'elle etait supportée par les 2.
C'est dur de faire du SQL ANSI, quand on utilise deja, depuis des lustres des bidouilles MySQL comme CALC_NUM_ROW ou UNIX_TIMESTAMP. Il n'y a pas moyen de faire la meme chose en SQL portable.
en PG oui, en My oui, en SQL Potable c'est une subquery de ouf illisible. Si on voulait faire du portable, il faudrait mettre cette subquery inbitable.
J'ai pu m'en debarasser grace a php dans certains cas, mais pas tous.

J'ai réécrit un paquet de code pour le rendre portable, je fais que ca depuis 1 semaine, avec ce seul objectif de portabilité, c'est l'unique interêt de PDO, qui a son lot de défauts.
Quand je n'ai pas trouvé de solution SQL portable, tu trouvera un flag FIXME POSTGRESQL a coté normalement.

En bref, t'inquietes pas , la portabilité, je n'ai que ça a la tête.
sly a écrit : 2) le code se retrouve partagé entre des "case" des "if" des "for" coté sql et coté php
constat: La meme requete, simple, est a plusieurs endroits du PHP, avec son lot de if/then PHP autour a chaque fois les memes.

mon point de vue etait de centraliser cette requete SQL, rassembler la complexité à l'endroit centralisé, pour qu'elle ne soit ecrite qu'une seule fois, et d'épurer le PHP.

Une autre solution, sans doute meilleure, eut été de centraliser le PHP dans une nouvelle fonction, et appeler celle ci de partout. Une fois qu'on aura un truc qui marche on pourra passer sur cette solution ?

Aucun probleme pour se débarasser des PDO prepare, j'y tiens pas, ca cree des problemes, ca en resoud aussi.
sly a écrit : 3) conceptuellement, sql c'est pour moi la zone de stockage, et des requêtes relationnelles avec index si on commence à y mettre des boucles, on va tout faire ramer sans s'en rendre compte
4) on commence par des if et dans 6 mois on aura des procédures stoquées en pl / pgsql ;-)
En passant, j'ai essayé d'exploiter les possibilités du standard SQL, par exemple, il n'y avait pas une seule subquery dans tout le site. ca fait gagner souvent 2 appels successifs a mysql_query, parfois 3 appels , jusqu'a 4 appels là ou 1 requete bien tournée, et SQL-compliant, suffit.
les subquery et des structure de controle c'est SQL-ANSI aussi.

C'est comme si on faisait du PHP en s'interdisant les boucles foreach et switch/case ;) elles sont pas moins standard.

La ou j'ai merdé, c'est que en meme temps, j'aurais du valider les regles de typage et de quote que PG recrachera. mais le SQL pur sera standard.


C'est pas bien les procedures stockées PG ?
On va quand meme centraliser le SQL quelque part un jour ?
comme le modèle MVC bien compartimenté tout ca ...
Avatar du membre
sly
Messages : 5041
Enregistré le : 29 févr. 2004, 17:59
Localisation : Chambéry - Savoie

Message par sly »

yip a écrit : C'est quoi factoriser ?
Factoriser c'est ce que tu essayes de faire, ce que je veux faire, et ce que tout développeur tente en général de faire :
- s'arranger pour qu'il n'y ait pas de duplication de code, de requêtes ou de page web.

Le problème précis des commentaires, c'est que personne n'a vraiment mis son nez dedans et que y'en a un peu partout.

Il y a seulement 2 mois que le fichier fonctions_commentaires.php existe, et pour l'instant seul une page ou 2 s'en servent (la gestion et l'ajout de commentaire) je n'ai pas encore migré le reste, et je n'ai pas encore écrit toutes les fonctions nécessaire pour justement "factoriser"

Par exemple, un bon paquet de variable numerique sont déclarées "$config = '5' ;" ce qui fera foirer PGSQL et passait MY.
donc toutes les modifs a faire partout, tu vois le topo, pour une requete identique.
Je vois bien le problème, problème qui doit être bien moindre quand on touche au points par exemple car là, j'ai beaucoup factorisé il y a un certain temps déjà.

En clair, oui il y'a des problèmes de duplication de code, pour autant, je ne suis pas sûr que la solution réside dans la technique $PDO->prepare (bien que ça soit une option tout à fait honorable à explorer)
En bref, t'inquietes pas , la portabilité, je n'ai que ça a la tête.
Je dirais qu'il ne faut pas non plus en faire une ligne de dév sans conditions. Oui si on peut rester portable, il faut le faire, maintenant, si ça nous bouffe notre temps, il faut pas en faire un drame (on va utiliser GIS et le retour arrière vers mysql ne sera pas portable, pour autant tant pis, on l'utilisera quand même)
sly a écrit : 2) le code se retrouve partagé entre des "case" des "if" des "for" coté sql et coté php
constat: La meme requete, simple, est a plusieurs endroits du PHP, avec son lot de if/then PHP autour a chaque fois les memes.
Tout à fait. il faut donc bien la mettre à un seul endroit, et ok, des if et case en SQL c'est assez limité, donc ok. Mais je me rappel du temps où tu avais réalisé un code (dans nouvelles je crois) qui faisait générer du HTML par mysql ! Si on commence à trop mettre de code dans SQL (genre avec les procédures stoquées) je pense qu'on augmenter les raisons de se perdre et s'embrouiller.
Une autre solution, sans doute meilleure, eut été de centraliser le PHP dans une nouvelle fonction, et appeler celle ci de partout. Une fois qu'on aura un truc qui marche on pourra passer sur cette solution ?
C'est cette solution que je défend en effet. ce qui aura pour même effet de réduire la quantité de php + réduire le nombre de correction à faire car si on change un champ de notre base, on réduit le nombre de correction à faire.
Toujours le même mot : factorisation ;-)
C'est pas bien les procedures stockées PG ?
Je ne connais pas trop donc je m'abstiendrais de juger la qualité, mais de ce que j'ai compris, c'est quelque chose qu'on va plutôt utiliser lorsque plusieurs programmes, codés en langages différents (C/perl/pph/java) attaquent une même bdd. Là, on factorise au niveau du sgbd commun à tous. Mais dans notre cas, je suis plutôt réservé.
PostGIS par exemple fait un usage énorme de procédure stoquées, mais avec une API standardisée (OpenGIS) et dans un objectif de fournir cette api à moulte langages.
On va quand meme centraliser le SQL quelque part un jour ?
comme le modèle MVC bien compartimenté tout ca ...
Je ne suis pas convaincu du tout du gain en temps. Pour ma part je préfère une logique :
- rassembler ce qui touche à un thème (les points ou les polygones ou les recherches ou ...) dans un même fichier (par des fonctions ou des classes), ainsi on a un oeil sur l'ensemble des choses qui vont traiter ce thème : sql, calcul, traitement images, ...

Je manque toutefois d'expérience pour juger comment font les autres projets et dire si oui ou non la centralisation de toutes les requêtes SQL apporte de la simplicité au développement.

Mais une de mes peurs, à vouloir trop généraliser les requêtes c'est qu'on finissent (en exagérant) avec un PDO->prepare de cette forme :

Code : Tout sélectionner

select :choix_champs from :choix_tables WHERE :conditions1 and :conditions2 :if_order :if_limit :if_offset
En clair, que ça deviennent tellement généraliste qu'on finisse par ne plus pouvoir lire la requête, ne plus la comprendre et aussi ne pas aussi facilement la debugger.

Exemple, (d'accord j'ai pas forcément bien cherché mais quand même), je voulais débugger cette requête qui foire :

Code : Tout sélectionner

	$pdo->requetes->liste_comments->bindValue('comment', -1 , PDO::PARAM_INT ); // -1 = tous
	$pdo->requetes->liste_comments->bindValue('point', -1 , PDO::PARAM_INT ); // -1 = tous
	$pdo->requetes->liste_comments->bindValue('vignette', $vignette ? $vignette : -1 , PDO::PARAM_INT ); // 1 avec, -1 tous , 0 sans
	$pdo->requetes->liste_comments->bindValue('limite', $nombre, PDO::PARAM_INT); //ATTENTION LIMIT attent un INT, ce qui fait foirer la methode array

	$pdo->requetes->liste_comments->execute() or die ("problème dans PDO liste_comments $vignette $nombre");
Et bien impossible de trouver comment l'afficher pour la tester "à la main" je ne savais pas ou coller un print() et ni dans quel sous variable de quel sous-objet elle pouvait se trouver

Alors que ça :

Code : Tout sélectionner

    $query_news=
		"SELECT extract('epoch' from date) as date,
			id_commentaire,
			texte
		FROM commentaires
		WHERE
			commentaires.id_point = ".$config['numero_commentaires_generaux']."
		ORDER BY date DESC
		LIMIT $nombre";
	$res = $pdo->query($query_news);
J'ai tout de suite compris que la requête, ben, elle était devant moi, et au pire, si elle contient des variables qui la génère, je fais un print($query_news) et c'est tout de suite concret.
Avatar du membre
yip
Messages : 387
Enregistré le : 08 mars 2004, 23:32

Message par yip »

ca roule,
pdo-> prepare a la trappe.
ca devenait merdique.
Factorisons.

Les procedures stockees PG, j'ai l'impression que c'est du code en langage PLSQL , donc pas portable

les VIEWS par contre, standard elles, m'ont l'air pleines d'avenir ?

ah j'y peux rien, les gros mix de PHP et de SQL ca fait bizarre,
(comme les mix HTML+PHP qui, longtemps après les avoir codés , font mal aux yeux maintenant)
mais je vais m'y faire :lol:
Avatar du membre
sly
Messages : 5041
Enregistré le : 29 févr. 2004, 17:59
Localisation : Chambéry - Savoie

Message par sly »

yip a écrit :ca roule,
pdo-> prepare a la trappe.
ca devenait merdique.
Si tu veux en laisser quelques unes pour qu'on se rendent compte à l'usage, je n'ai rien contre hein ? si vraiment c'est bien, on démocratissera, si c'est merdique, on remplacera.
Les procedures stockees PG, j'ai l'impression que c'est du code en langage PLSQL , donc pas portable
PL/SQL c'est propriétaire oracle, PG utilise une variante "presque compatible" appelée PL/pgSQL
http://fr.wikipedia.org/wiki/PL/pgSQL

Bref, chaque sgbd à son propre langage
les VIEWS par contre, standard elles, m'ont l'air pleines d'avenir ?
Je n'ai rien contre, si ça peut factoriser un peu certaines requêtes pourquoi pas, mais si on se retrouve avec une vue par requête, on a rien gagné du tout.

Pour info, je ne sais pas si c'est le cas, mais une croyance populaire voudrait que les vues accélèrent les requêtes en faisant une sorte de "pré-machage" et donc beaucoup veulent les utiliser pour ça, mais point du tout, les vues sont ni plus ni moins que l'équivalent des requêtes imbriquées, mais avec persistance en base.
ah j'y peux rien, les gros mix de PHP et de SQL ca fait bizarre,
On peut déjà essayer des les "templater" dans le code afin de les rendre plus lisible plutôt que de les construire par petits bouts pour faire un gros collage final difficile à comprendre.
Mais bon, il faut bien choisir entre factorisation maximale et lisibilité.
(comme les mix HTML+PHP qui, longtemps après les avoir codés , font mal aux yeux maintenant)
mais je vais m'y faire :lol:
ça, tu peux te lâcher, on essaye de tout passer par des vues (/vues) qui sont en gros des templates HTML avec comme nouveau slogan :
Plus une seule ligne de html ailleurs que dans /vues

et crois moi, c'est pas encore gagné ;-)