GERER UN ENTREPOT VIA PHP 5 MYSQL VERSION OBJET ( PDO)

cs_yoman64 Messages postés 592 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 4 décembre 2008 - 31 mars 2008 à 13:43
masternico Messages postés 487 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 1 septembre 2011 - 7 avril 2008 à 16:16
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/46238-gerer-un-entrepot-via-php-5-mysql-version-objet-pdo

masternico Messages postés 487 Date d'inscription dimanche 5 octobre 2003 Statut Membre Dernière intervention 1 septembre 2011
7 avril 2008 à 16:16
Salut,

Je suis d'accord avec malalam quand il parle de mysql_insert_id(), mais quand je fait des ajouts d'enregistrements dans une base de données avec liens multiples et opérateurs multiples, je préfère mettre un verrou en écriture sur les tables concernées('LOCK TABLES `articles` WRITE, `magasins` WRITE, `articles2magasins` WRITE'). Comme ça, je suis sûr de ne pas avoir de croisements de références et puis, le traitement des instructions est plus rapide en faisant comme ça.
Donc, au pire, ça bloque l'opérateur suivant pendant un quart de seconde mais ça simplifie la tâche de contrôle d'insertion.
fabienenvac Messages postés 19 Date d'inscription jeudi 6 décembre 2007 Statut Membre Dernière intervention 17 mai 2008
1 avril 2008 à 17:41
effectivement il manque des morceaux, la je suis entrain de tous transformer mes requêtes avec pdo.
je pense donc pouvoir mettre en ligne le reste d'ici ce soir et après réfléchir sur des objets propres a l'entrepôt.
Si qqn peut me donner un exemple afin de transmettre mon objet connexion cela serait appréciable.
merci
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
1 avril 2008 à 16:45
Hello,

à 16h45 (heure française), il manque des morceaux, non...?
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
1 avril 2008 à 15:38
ta source fait un peu vide maintenant... t'as mis une classe pdo, mais t'as vire le reste...

personellement, j'aurais imagine un truc genre :

Entrepot ---> arrayAcces
---> Itterator
---> Countable (c'est peut-etre pas vraiment utile ici)

ProduitNotFound ---> EntrepotException ---> Exception
QuantiteNegative ---> EntrepotException ---> Exception

Produit ---> SqlElement (si je mets sqlElement, c'est pour dire qu'on peut en ajouter, en supprimer, en mettre a jours, et que c'est directement relie a du sql, c'est donc pas une classe mais une interface qu'il faut faire ici)

et tu mets un array de Produit dans l'Entrepot (en private evidement)

si tu veux t'amuser avec une syntaxe marrante, tu peux mettre Produit implements coutable, ca te permettrait de faire un truc genre :

$a=Produit::GetById(15);
echo 'il y a '.count($a).' produits dans l\'entrepot.';

si tu veux lister les deplacements de produits (entrees, sorties) tu peux t'amuser a donner a produit le meme genre d'interfaces (itterator) et a ajouter trois classes pour ces entrees, sorties (une E, une S, et une interface ou abstraite).
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
31 mars 2008 à 23:34
Non, ne lançons pas le débat ici (manque un espace de discussion pérenne quand même, sur ce site!), mais Marcus est quand même plein de contradictions vu le fonctionnement des exceptions en php...et la façon dont elles sont utilisées dans certaines fonctions built-in de php.
Ceci dit, à de rares exceptions (si j'ose dire) près, c'est bien ainsi que je les utilise : le code s'arrête car il est tombé sur un os, et après quelques petites manipulations de sécurisation/log, on dégage.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
31 mars 2008 à 23:18
@Malalam :

"une exception n'empêche pas de continuer un code (après le catch)"

Certes... Mais je crois que je vais lancer un vrai débat sur la question... Marcus Börger (un des auteurs de php) a dit :
"Respect these rules :
- Exceptions are exceptions
- Never use exceptions for control flow
- Never ever use exceptions for parameters passing"
Cf : http://somabo.de/talks/#20050401

Mais c'est pas vraiment l'endroit pour en parler... Cependant, c'est vraiment une question qu'on devrait aborder pour de vrai un de ces jours...
malalam Messages postés 10839 Date d'inscription lundi 24 février 2003 Statut Membre Dernière intervention 2 mars 2010 25
31 mars 2008 à 22:55
Hello,

sans forcément exploiter une abstraction DB, je pense quand même que séparer la connexion des classes utilisatrices est une bonne idée. Créer une classe éventuellement statique gérant les connexions aide pas mal, ne serait-ce que ça. Et du coup ajouter une surcouche gérant les fonctions habituelles ET tant qu'à faire ça, en ajoutant de nouvelle ou facilitant certains aspects récurrents. Ca a l'avantage de, si un jour il passe des fonctions mysql_* à mysqli_* (désirant gérer les transactions, par exemple -mêm si on peut tjrs avec mysql_* hein...-, ce qui dans le cadre d'une gestion logistique est toujours une bonne idée...j'en sais quelquechose...), cela évitera de se retaper toutes les classes utilitaires à la main. On ne change que la classe connecteur.
Mais j'insiste sur le fait qu'une classe wrappant la db est très bien, surtout pour y ajouter des fonctionnalités toujours bienvenue.

Concernant la gestion des erreurs, je rejoins à peu près Neige sauf qu'une exception n'empêche pas de continuer un code (après le catch), et qu'un trigger_error() permet aussi de lever des erreurs fatales.

Concernant le code, tu sais qu'il existe une fonction mysql_insert_id() ? Parce que bon, créer une palette puis faire une requête allant chercher le MAX(id) ensuite pour récupérer l'id créé...sachant qu'en plus, ce ne sera pas forcément le bon, pour peu que 2 préparateurs créent une palette en même temps.
Je ne comprends pas ce que fait combo_nom_article() dans cette classe, par contre ?
Moi, je ferais plus de classes par la suite, si j'étais toi.
T'as un entrepôt, ok. Tu as des emplacements dans cet entrepôt. L'entrepôt connait sa modélisation. Eviudemment, l'emplacement ne se connait que lui-même, et éventuellement la référence qu'il stocke.
Tu as des références : on les crée, et elles ont des "propriétés" : date de péremption peut-être ? Une unité de gestion forcément. Un comptage. Peut-être un seuil d'alerte, etc.
Tu as des approvisonnement : un appro contient x références, sur x palettes généralement (voire même, est livré par un transporteur et/ou un fournisseur). Un approvisionnement donne lieu à x réceptions...une réception, c'est une référence que l'on place sur n emplacements, mais que l'on compte auparavant (comptage exhaustif, par sondage, apparent...). Ah, et un emplacement a une hauteur, une profondeur, à minima, et on peut y placer un certain nombres de contenants : palettes dont les dimensions conviennent, colis, casiers etc...
etc etc...
A toi de trouver les bons objets à utiliser pour valider ton process, et surtout pour couvrir l'exhaustivité des besoins des gars de l'entrepôt (du préparateur au chef d'entrepôt). Mais à mon avis, tu t'es mal engagé avec cette classe qui recouvre trop de choses différentes, et trop peu de spécifiques à la fois.
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 19
31 mars 2008 à 21:54
Salut,

Je rejoins a priori l'avis de Yoman64 et Coucou747.
Sauf concernant l'abstraction de base de données. A croire que si on n'utilise pas une classe d'accès au SGBDR abstraite qui permet d'utiliser MySQL aussi bien que PgSQL, ORacle, MSSql ou autre, c'est mal. Moi, je ne suis pas d'accord. Quand on travaille pour soi, qu'on n'utilise que MySQL, qu'on n'utilisera jamais rien d'autre que MySQL, qu'on ne publiera jamais son code source pour le partager, je ne vois vraiment pas l'intérêt d'utiliser une classe d'abstraction.

Pour en remettre une couche quant au HTML dans la classe : l'idéal est de séparer le traitement de l'affichage. C'est plus facile pour la maintenance et l'évolution du site. L'idéal pour cela étant d'utiliser un système de templates (entendre par là, une mise en forme automatisée des données d'après des gabarits, pas forcément utiliser Smarty ou autre moteur).
La logique veut qu'une classe de traitement de données va traiter les données, et uniquement ça. Leur affichage doit pouvoir se gérer séparément (ce qui permet de modifier la sortie, sans toucher au traitement, par exemple, produire du HTML, ou alors du XML pour utiliser sur un extranet, du PDF, et j'en passe).

Quant aux erreurs, jette un oeil aux exceptions et à trigger_error() : toujours pareil... Une classe, si elle ne peut pas travailler, va s'arrêter, et c'est le reste du programme qui se charge de gérer l'erreur. De ce côté là, t'es pas très loin de l'idée... Mais tu as encore du code redondant que tu pourrais factoriser. Pour cela, tu peux définir un gestionnaire d'erreurs (voir : set_error_handler() et set_exception_handler()). Ta classe se contente de générer une erreur (avec trigger_error si ce n'est pas une erreur fatale, ou throw new Exception si c'en est une) qui sera gérée par le gestionnaire : ça te permet de modifier plus tard la manière dont tu gères les erreurs (simple affichage, log dans un fichier, ...) sans avoir besoin de te retaper tout ton code pour changer 250 fois les mêmes lignes.
coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
31 mars 2008 à 14:17
tu devrais aussi separer les appels a mysql de tes classes (mettre ca dans une autre classe, faire de l'abstraction de databse)

une proposition d'amelioration interessante : la SPL te propose des interfaces et classes tres utiles qui te permettent de faire des itterators (tu peux faire ensuite un foreach sur des objets), des coutable (tu peux compter a l'aide de la fonction count, le nombre de choses que t'as dans ton objet), ou arrayacces (tu peux utiliser $objet[truc]) pour un entrepot, ca peut-etre assez utile.

http://fr.php.net/manual/nl/ref.spl.php

et pour eviter les includes, tu peux faire appel a une fonction autoload pour charger automatiquement les classes dont tu as besoin, quand tu en as besoin. Ca prend seulement quelques lignes et ca t'evite de t'embeter avec les chemins qui menent a tes classes

bonne continuation :)
cs_yoman64 Messages postés 592 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 4 décembre 2008
31 mars 2008 à 13:43
Salut,

Euh j'ai peut être mal vu, mais tu ne déclare même pas tes variables de classe... tu appeles $this->var sans arrêt, mais je ne vois null part ou tu les à déclarées...

Tant qu'à faire du php5 tu devrais déclarer la porté de tes méthodes (public,private) et de tes variables (si tu les déclarait...).

Ensuite attention, tu n'échappes pas les arguments que tu passe à MySql, donc l'injection est possible... (Peut être que tu le fais en dehors de la classe, j'ai pas regardé, après tout l'attrait de ta source a t'entendre c'était la classe).

Ta classe renvoit souvent du html ou du texte via des echo, c'est très mauvais, apprends à utiliser les exceptions ou gère les erreurs en dehors de ta classe.

Bref encore beaucoup de boulot, mais ne te décourage pas :)
Rejoignez-nous