IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

Avis théorique lors d'une sauvargarde d'un formulaire


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3
    Par défaut Avis théorique lors d'une sauvargarde d'un formulaire
    Salut,

    Prenons l'exemple suivant :
    Un site web de gestion de livre où le membre doit s'identifier pour accéder au contenu.
    Ce site est couplé avec une base de données (MySQL).
    L'une des pages du site permet d'afficher le détail d'un livre.
    Si le détail de livre se trouve déjà dans la base alors la page affiche les infos dans des zones texte donnant la possibilté aux membres de modifier les zones à l'aide du bouton "Modifier".
    Dans le cas contraire, les zones textes sont vide et un bouton "valider" est présent.

    Dans les deux cas, j'utilise une zone en hidden qui me permet de savoir si je suis en "Validation" ou en "Modification".

    Coté serveur, je teste donc cette zone et je décide de faire soit un INSERT soit un UPDATE. Jusque là pas de problème.

    Cependant, j'ai remarqué qu'avec IE, on peut ouvrir la même page dans une autre fenêtre (CTRL+N).

    Ma page de départ est de type "VALIDER" (=le membre doit donc valoriser le formulaire). Le membre clique sur valider et le processus se passe bien.
    Comme le membre avait ouvert cette même page une deuxième fois, il clique aussi sur "VALIDER". Là il y a une erreur SQL car duplication de clé ! Ce qui est logique.

    Je me pose donc la question suivante :
    Dans tout les tutos de validations de formulaires, aucun test n'est réalisé si l'enregistrement est déjà réalisé.
    Théoriquement que faudrait-il faire ? Tester avant tout INSERT, si les données sont présentes ou non ?

    Qu'en pensez-vous ?

    Merci

  2. #2
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Salut

    Techniquement, tu peux utiliser REPLACE INTO et ne pas t'embêter outre mesure... Fais juste gaffe à ta clé primaire dans la liste des champs.

    Sinon, tu n'es pas obligé de laisser les infos de debug lorsque le site est en production : tu peux zapper le or die(), ce qui fait que ta requête s'exécute et plante éventuellement, le tout silencieusement. Pas grave s'il y a doublon, personne ne le saura.

    Logiquement, tu ne devrais pas avoir ce problème avec un INSERT INTO correctement écrit : tu ne devrais pas spécifier la clef, qui devrait être auto_increment, donc il ne devrait jamais y avoir de souci de duplicata lors d'un INSERT INTO classique.

  3. #3
    Membre Expert
    Avatar de ska_root
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    1 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Août 2005
    Messages : 1 203
    Par défaut
    Citation Envoyé par Kirkis
    tu ne devrais pas spécifier la clef, qui devrait être auto_increment, donc il ne devrait jamais y avoir de souci de duplicata lors d'un INSERT INTO classique.
    tu fatigues Kirkis , il n'y a pas de doublons possibles sur la même clé bien évidemment, mais il peut enregistrer 2 fois le même enregistrement avec une clé différente... je crois que c'est là le problème

    par contre la solution avec REPLACE me plait bien, seul inconvénient, obligé de récupérer le dernier indice.

  4. #4
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Si, si, il parle d'erreur MySQL pour cause de duplication de clé donc c'est bien que Matlau spécifie la clé à chaque enregistrement. J'imagine qu'il a fait un SELECT MAX(id) plutôt que de laisser MySQL se charger de l'auto_increment.
    Si MySQL parle de duplicata, alors cela signifie que la clef n'est pas différente ^^

  5. #5
    Membre Expert
    Avatar de ska_root
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    1 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Août 2005
    Messages : 1 203
    Par défaut
    Citation Envoyé par Kirkis
    Si, si, il parle d'erreur MySQL pour cause de duplication de clé
    au temps pour moi, c'est donc moi qui fatigues...

  6. #6
    Membre chevronné Avatar de XtofRoland
    Profil pro
    Inscrit en
    Août 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 357
    Par défaut
    perso, je choisi au dernier moment entre le update et le insert.

    si ma variable $id == "" => 1) select max(id) suivit du insert
    sinon update avec where id=$id;

    c'est mal expliqué mais le principe y est ;-)

  7. #7
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    C'est surtout foireux : le champ auto_increment est --> LA <-- solution pour les requêtes INSERT... Ne faites surtout pas de SELECT MAX(id)+1
    Combien de fois devrons-nous le dire ?

  8. #8
    Membre chevronné Avatar de XtofRoland
    Profil pro
    Inscrit en
    Août 2005
    Messages
    357
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2005
    Messages : 357
    Par défaut
    je ne suis pas d'accord avec toi!
    l'auto incrément est une solution facile et sans doute tres propre, et meme la solution dans les tables ou il y a peu de mouvement .

    mais si c'est une table ou je sais qu'il y aura bcp d'insert delete, je prefere recuperer les clefs perdues.
    j'utilise soit une boucle for sur les clef je compare la clef au $i++ et des que c diff c'est une clef de libre
    ou j'utilise une table pour stocker les clef libres par range

    quoi que avec les trigger je devrait pe revoir ma facon de faire ;-)

  9. #9
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    J'aimerais bien qu'un rédacteur BDD vienne donner son avis, il aurait plus de poids que le mien.

    Je ne suis pas d'accord, l'auto_increment est là pour cela, il faut l'utiliser si c'est cohérent. Entre autres avantages, cela permet, simplement en récuparant la valeur de l'auto_increment, de savoir combien d'enregistrements ont été faits depuis la création de la table. Autre avantage et non des moindres : ne pas te compliquer la vie avec des traiements qui n'ont vraiment aucune utilité.

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3
    Par défaut
    Merci pour vos réponses.
    Pour information : Ma table possède bien un id auto incrément mais je me base pas du tout sur cette id.
    En faite, cette même table possède deux clés et je me base uniquement sur ces deux clés.
    Dans mon formulaire, je connais les valeurs des deux clés.

    Lors du premier enregistrement (donc INSERT), l'insertion se passe bien.
    Si on refait un INSERT avec les mêmes infos sur les clés --> Erreur, ce qui est logique.

    J'en déduis donc que je dois absolument faire un test afin de vérifier s'il existe déjà un enregistrement avec les deux clés. Si oui UPDATE, si non INSERT.
    Actuellement ce test, je le fais avant d'afficher la page et je mets un flag dans une zone en hidden sur laquelle, je me base dessus après le submit.

    Ce problème arrive quand un utilisateur ouvre deux fois le formulaire avant de valider la page.
    Théoriquement, comment faire au mieux ?

    EDIT : Je viens de remarquer que ce forum gère très bien le système d'INSERT/UPDATE.
    Exemple : Quand vous répondez à ce message, juste avant de valider votre réponse, faite CTRL-N sous IE (cela ouvre une nouvelle fenêtre).
    Modifier votre texte dans la nouvelle fenêtre.
    Valider votre message dans la première fenêtre et attendre quelque temps avant d'en faire de même sur l'autre fenêtre.
    Votre message a bien été modifié.
    j'en déduis donc qu'un test est réalisé juste avant l'INSERT.

    TEST

  11. #11
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Lol ^^

    Je reprends :
    Si tu souhaites modifier quelque chose, c'est que ce auelque chose est déjà dans la BDD, certainement avec un ID. C'est ce qu'il se passe ici pour éditer une message par exemple, il ne s'agit pas de faire un INSERT mais un UPDATE.

    En revanche, si tu souhaites ajouter un élément dans ta BDD, alors il n'y a pas encore d'ID à cet élément puisqu'il n'est pas dans la BDD (logique).
    Perso, pour réutiliser mon code (ainsi que pour une foule d'autres raisons), j'utilise un moteur de templates. Pour réutiliser le code du formulaire, j'utilise un champ caché de nom "mode" et de valeur "insert" ou "update". Dans le cas du update, il y a un champ supplémentaire "id".

    Dans le script de destination, je teste $_POST['mode'] avec un switch. Si je suis dans le cas d'un insert, je ne spécifie pas la clef primaire ; dans le cas d'un update, j'utilise le champ $_POST['id'].
    Avec cette méthode, je n'ai jamais eu ce souci auquel tu es confronté.

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3
    Par défaut
    Je me suis peut être mal exprimer :-)
    Je sais très bien ce qu'est un INSERT et un UPDATE ;-)))

    Perso, j'utilise aussi ton principe du champ caché qui me permet de dire si je suis update ou insert.
    Là n'est point le problème !

    En revanche, si tu souhaites ajouter un élément dans ta BDD, alors il n'y a pas encore d'ID à cet élément puisqu'il n'est pas dans la BDD (logique).
    Partons donc sur cette exemple (c'est le seul qui m'interesse).
    Tu affiches un formulaire vide avec en hidden mode="insert" (vu que tu n'as rien dans ta base de donnée).

    Avant de valider ton formulaire, appuis sur CTRL+N de ton navigateur IE. Là tu as une nouvelle fenêtre avec ton formulaire (à saisir) qui s'affiche (et donc aussi ta zone en hidden mode=insert).

    Tu valides ton formulaire sur la première fenêtre. Tu tests la zone "mode". Elle est en "insert" donc tu lances la requête INSERT. Aucun problème jusque là.
    Maintenant, tu valides ton formulaire qui se trouve dans ta 2ème fenêtre.
    La zone en hidden est égale à "insert"...tu vas donc faire un INSERT.
    Si ta base à un seul clé, l'ID auto-incrément, tu n'auras pas de message d'erreur, et ton formulaire sera bien sauvegardé. Par contre tu auras deux fois les même infos dans ta base.
    Si ta base possède deux clés (mon cas), le deuxième INSERT va engendrer une erreur (logique).
    Pourtant je me suis basé sur la zone mode....

    Vois tu ce que je veux dire ?

  13. #13
    Rédacteur

    Avatar de Yogui
    Homme Profil pro
    Directeur technique
    Inscrit en
    Février 2004
    Messages
    13 721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yonne (Bourgogne)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Février 2004
    Messages : 13 721
    Par défaut
    Oui, je vois, et en ce cas tu devrais utiliser REPLACE INTO plutôt que INSERT INTO, ou bien ne pas afficher les erreurs d'insertion. Tout dépend de ta politique : soit (1° cas) tu considères que l'utilisateur envoie une version plus récente du même formulaire, soit (2° cas) tu considères qu'il l'a envoyé par erreur (donc tu l'ignores).

Discussions similaires

  1. Réponses: 16
    Dernier message: 04/08/2006, 14h14
  2. Mauvais noms de colonnes lors d'une requête
    Par nmathon dans le forum Bases de données
    Réponses: 2
    Dernier message: 09/04/2004, 07h27
  3. Combler les trous lors d'une suppression dans une table
    Par Billybongjoe dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 08/04/2004, 14h02
  4. Erreur lors d'une requete INNER JOIN
    Par k-lendos dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/03/2004, 15h09
  5. Enlever la surbrillance lors d'une recherche avec vi
    Par sekiryou dans le forum Applications et environnements graphiques
    Réponses: 8
    Dernier message: 04/03/2004, 13h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo