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 :

Ecriture de données avec PHP et clés étrangères


Sujet :

PHP & Base de données

  1. #1
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut Ecriture de données avec PHP et clés étrangères
    Bonjour,

    Je travaille sur la création d'une base de données qui sera alimentée par des formulaires HTML/CSS avec du PHP pour la récupération des informations saisies et l'écriture dans la base (classique, j'imagine). Je m'interroge sur la gestion des clés étrangères. Un exemple simple avec les tables suivantes :

    - intervention (int_id, int_date, int_type)

    - agent (age_id, age_prenom, age_nom)

    - intervention_agent (int_id, age_id)

    La table intervention_agent stocke les correspondances entre les tables intervention et agent car il peut y avoir plusieurs agents pour une même intervention.


    En PHP, je procède de la manière suivante (volontairement simplifiée mais c'est pour le principe) :

    1. Récupération des informations saisies dans des variables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $date = $_POST['date'];
    $type = $_POST['type'];
    $prenom = $_POST['prenom'];
    $nom = $_POST['nom'];
    2. Requêtes d'écriture des informations dans les tables :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention (int_id, int_date, int_type) VALUES ('', '$date', '$type');');
    $rqt_intervention->execute();
     
    $rqt_intervention_agent = $bdd->prepare('INSERT INTO intervention_agent (int_id, age_id) VALUES ( ??? );');
    $rqt_intervention_agent->execute();

    Ma question : comment se gère l'écriture des clés étrangères dans la table intervention_agent ? En effet, j'ai bien paramétré les champs int_id et age_id comme clés primaires dans PostgreSQL, donc mes requêtes d'écriture laissent vides ces champs qui seront automatiquement numérotés à la suite par PostgreSQL lors de l'écriture. Mais quelles valeurs dois-je indiquer dans ma requête d'écriture dans la table intervention_agent (cf. mes points d'interrogation dans la dernière requête ci-dessus) ? Là, je ne vois pas bien comment ça se passe, sur le principe...

    Merci par avance pour votre aide !

    Thomas

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Ne mets pas les champs autoincrementés dans ta requête d'insertion
    Puisque tu utilises des requêtes préparées, fais le jusqu'au bout en utilisant des paramètres.

    Pour recuperer l'id créé, tu peux utiliser RETURNING :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention ( int_date, int_type) VALUES (:int_date, :int_type) returning int_id;');
    $rqt_intervention->execute(array(':int_date'=>$date, ':int_type'=>$type);
    $row = $rqt_intervention->fetch();
    $int_id = $row[0];
    Pour l'agent de l'id, c'est à toi de le spécifier, postregs ne peut pas le deviner.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut
    Salut,

    Merci pour ta réponse ! Alors là je découvre le truc totalement... Je ne suis pas sûr de saisir le sens du code proposé... Je te propose mon interprétation pour chaque ligne. Si tu peux compléter les points qui me posent problème, ce serait vraiment super !


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention ( int_date, int_type) VALUES (:int_date, :int_type) returning int_id;');
    Je prépare ma requête d'insertion. Je ne mentionne pas la colonne de clé primaire et elle n'apparaît donc pas dans les VALUES. C'est quoi « :int_date et :int_type» ? Que signifient les « : » devant ? Que signifie « returning » ?



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rqt_intervention->execute(array(':int_date'=>$date, ':int_type'=>$type);
    J’exécute ma requête, OK. Pourquoi un tableau ? A priori, je ne vais avoir qu'une seule ligne de renseignée dans ma table intervention... Par contre, je vais en avoir potentiellement plusieurs dans ma table intermédiaire intervention_agent.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $row = $rqt_intervention->fetch();
    Je créé une variable $row qui va désigner la première ligne du tableau déclaré précédemment (c'est bien ça le sens de fetch() seul ?).



    Je créé une variable $int_id qui va prendre pour valeur l'indice de la première ligne du tableau.



    Merci beaucoup d'avance !


    Thomas

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Il s'agit d'une requête préparée : elle sépare la structure SQL et les valeurs.

    :int_type et :int_date sont des marqueurs representant les valeurs.
    execute() prend en argument les valeurs à placer sous la forme d'un tableau avec :marqueur=>vrai_valeur.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut
    Re !

    Merci pour ton message... Seulement, ça ne m'éclaire pas plus que ça sur le principe dont les clés étrangères vont être écrites dans ma table intermédiaire intervention_agent. J'avais d'autres questions dans mon message que j'ai essayé de poser clairement et à côté du code concerné pour que tu puisses me répondre plus simplement, mais... tu ne réponds qu'à la toute première des questions. Tu n'as peut-être pas le temps, ce que je peux comprendre. Mais là, je ne suis pas vraiment avancé. Si tu pouvais reprendre les différentes questions et développer un peu, ça m'aiderait bien .

    Merci !

    Thomas

  6. #6
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut
    Pourquoi tu utilises un tableau ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $rqt_intervention->execute(array(':int_date'=>$date, ':int_type'=>$type);
    $row = $rqt_intervention->fetch();
    $int_id = $row[0];
    A priori, je ne vais avoir qu'une seule ligne renseignée dans ma table intervention... Par contre, je vais en avoir potentiellement plusieurs dans ma table intermédiaire intervention_agent.

    Est-ce une étape indispensable pour récupérer l'id généré automatiquement ?

    Thomas

  7. #7
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Pour le reste tu avais bon donc je n'ai rien dit

    Visiblement je t'ai emboruillé en introduisant une requête préparée.
    Une requête préparée est une requête pour laquelle tu isoles la requête proprement dite des valeurs qui font servir dedans, ceci en particulier afin de se protéger des injections SQL.

    Toi tu faisais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention (int_id, int_date, int_type) VALUES ('', '$date', '$type');');
    $rqt_intervention->execute();
    Tu utilisais déjà la preparation de requête (->prepare) mais en mettant directement tes variables dans la chaine de requête.

    La bonne méthode est de mettre des marqueurs à la place des valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention (int_date, int_type) VALUES (:int_date, :int_type);
    et de fournir les valeurs au moment de l'execution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rqt_intervention->execute(array(':int_date'=>$date, ':int_type'=>$type);
    Ca c'est pour la partie execution de la requête.
    Cette requête va créer un nouvel ID dans ta table intervention; tu vas avoir besoin de cet id pour faire ensuite les insertion dans ta table intervention_agent.

    Postgresql peut fournir, en retour de la requête INSERT, l'id qu'il a créé ; on utilise RETURNING.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $rqt_intervention = $bdd->prepare('INSERT INTO intervention ( int_date, int_type) VALUES (:int_date, :int_type) RETURNING int_id;');
    et effectivement je "fetch" l'unique et première valeur de l'unique et premier résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $row = $rqt_intervention->fetch();
    $int_id = $row[0];
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  8. #8
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut
    OK super ! Ça c'est très clair... Merci beaucoup pour le temps pris pour répondre. Je comprends mieux le sens du tableau, du coup.


    Allez, deux petits derniers trucs qui me gènent et ça devrait être nickel :

    1. Je peux donc récupérer $int_id pour l'insérer dans ma table intervention_agent, comme ci-dessous. Peux-tu me valider ça ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $rqt_intervention_agent = $bdd->prepare('INSERT INTO intervention_agent (int_id, age_id) VALUES (:int_id, :age_id);');
    $rqt_intervention_agent->execute(array(:int_id=>$int_id, :age_id=>$age_id));


    2. Je peux avoir plusieurs agents pour une même intervention. Du coup, mon instruction d'écriture dans la table intervention_agent doit en tenir compte... Je flaire bien une petite boucle derrière tout ça, non ? Dans mon formulaire, j'ai une liste déroulante (<select>) multiple. Donc $age_id peut stocker plusieurs valeurs... Est-ce qu'un truc comme ça pourrait convenir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    foreach $age_id as $un_age_id {
         $rqt_intervention_agent = $bdd->prepare('INSERT INTO intervention_agent (int_id, age_id) VALUES (:int_id, :age_id);');
         $rqt_intervention_agent->execute(array(:int_id=>$int_id, :age_id=>$un_age_id));
    }


    Merci pour ton avis et tes corrections éventuelles !


    Thomas

  9. #9
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    C'est ça sauf qu'on prépare une seule fois la requête et qu'on l'execute plusieurs fois.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $rqt_intervention_agent = $bdd->prepare('INSERT INTO intervention_agent (int_id, age_id) VALUES (:int_id, :age_id);');
     
    foreach $age_id as $un_age_id {     
         $rqt_intervention_agent->execute(array(:int_id=>$int_id, :age_id=>$un_age_id));
    }
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  10. #10
    Membre à l'essai
    Homme Profil pro
    Technicien Systèmes et réseaux
    Inscrit en
    Janvier 2013
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Technicien Systèmes et réseaux
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 36
    Points : 18
    Points
    18
    Par défaut
    Salut,

    En fait, mon formulaire est organisé comme sur l'image en pièce jointe : je sélectionne un à un les agents dans la liste déroulante de gauche et je les passe dans la liste de droite au clic sur la petite flèche bleue. Ainsi, je récupère ma sélection dans ma liste de droite. C'est la variable $resu_agent qui stocke la sélection.

    Pour alimenter ma table intermédiaire intervention_agent, je dois donc récupérer l'id des agents sélectionnés. Ces id correspondent aux value des <option> qui constituent ma liste de droite.

    Pour écrire les id dans la table (et non le nom des agents), je propose plutôt ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $rqt_intervention_agent = $bdd->prepare('INSERT INTO intervention_agent (int_id, age_id) VALUES (':int_id', ':resu_agent');');
     
    for($i=0 ; $i<sizeof($resu_agent) ; $i++) {     
         $rqt_intervention_agent->execute(array(':int_id'=>$ope_id, ':resu_agent'=>$resu_agent[i]));
    }
    Est-ce correct ? Penses-tu que je vais bien récupérer l'id des agents de cette manière ?


    Merci encore pour ton aide ...et ta patience !!


    Thomas
    Images attachées Images attachées  

Discussions similaires

  1. [MySQL] exporter une base de donnée avec php
    Par gtraxx dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 10/03/2009, 22h37
  2. [MySQL] Connexion à une base de données avec php-gtk
    Par mawusse dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 12/09/2007, 18h30
  3. Réponses: 4
    Dernier message: 30/03/2007, 18h42
  4. [SQL] Importer un fichier .sql dans une base de données avec PHP
    Par budiste dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 23/06/2006, 14h15

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