Champs select multiple qui alimente un champs clé étrangère [Résolu]

alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 12:10 - Dernière réponse : alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 21:14
Bonjour,
Comme le titre l'indique, j'ai un select multiple qui alimente un champs avec l'attribut clé étrangère de ma base de données.
Le soucis c'est que je voudrais que ce champs prennes plusieurs valeurs et je ne veux faire qu'un seul enregistrement. Je doute que ça soit faisable, mais je suis bloqué :(
voila la structure de mes tables :
--
-- Structure de la table `extras`
--

CREATE TABLE `extras` (
`id_extra` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(20) NOT NULL,
  `prix` text NOT NULL,
  PRIMARY KEY (`id_extra`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Contenu de la table `extras`
--

INSERT INTO `extras` (`id_extra`, `nom`, `prix`) VALUES
('', 'Ext1', '0'),
('', 'Ext2', '0');

-- --------------------------------------------------------

--
-- Structure de la table `types`
--

CREATE TABLE `types` (
`id_type` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(30) NOT NULL,
  `descr` varchar(100) NOT NULL,
  `ext` int(11) NOT NULL,
  PRIMARY KEY (`id_type`),
  CONSTRAINT fk_id_extra          
        FOREIGN KEY (ext)            
        REFERENCES extras(id_extra)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

mon formulaire :
<form action="" method="post">
<div>
                    <input type="text" id="type" name="type">
                  </div>
                  <div>
                      <textarea rows="3" id="desc" name="desc" placeholder="..."></textarea>
                  </div>
<div>
                  <?php 
$sql1="SELECT * FROM `extras`";
$reponses1=$conn->query($sql1);
$donnees1 =$reponses1->fetchAll(PDO::FETCH_ASSOC);
?>
                  
                    <select multiple id="ext" name="ext[]" >
                    <option value="">-- Choisir --</option>
                    <?php
    foreach($donnees1 as $donnees1)
    {
  

 $s1 = $donnees1['nom'];
 $s2 = $donnees1['id_extra'];
  ?>
                        <option value="<?php echo $s2;?>"><?php echo $s1;?></option>
                         <?php } ?>
                      
                      </select>
                  </div>
</form>

et voila le fichier de traitement :
(-j'avais testé de faire 1 enregistrement pour chaque valeur de 'ext' mais cette solution n'est pas vraiment top)
<?php 
$type = !empty($_POST['type']) ? $_POST['type']: NULL;
$desc = !empty($_POST['desc']) ? $_POST['desc']: NULL;
$desc=htmlspecialchars(ltrim(rtrim($desc)), ENT_QUOTES);
foreach($_POST['ext'] as $exti) {
  $req = $conn->prepare("INSERT INTO `types`(`id_type`, `type`, `descr`, `ext`) VALUES (:id_type, :type, :descr, :ext)");
   $inser_exec = $req->execute(array(
            "id_type" => '', 
            "type" => $type,
   "descr" => $desc,
   "ext" => $exti,
            )); 
   
   }

?>

dans cet exemple, je voudrais qu'un type X aie les valeur (ext1,ext2) à la fois, j'ai éssayé aussi de mettre le champs ext en varchar mais ça n'a pas marché puisque 'id_extra' est integer.
Merci d'avance pour votre aide.
Afficher la suite 

Votre réponse

9 réponses

jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
- 22 févr. 2016 à 13:16
0
Merci
Bonjour,


Le soucis c'est que je voudrais que ce champs prennes plusieurs valeurs et je ne veux faire qu'un seul enregistrement

Tu veux dire une seule ligne dans ta table TYPE mais pouvant avoir plusieurs EXT ?
Dans ce cas, utilises le SERIALIZE...
http://php.net/manual/fr/function.serialize.php

<?php 
$type = !empty($_POST['type']) ? $_POST['type']: NULL;
$desc = !empty($_POST['desc']) ?htmlspecialchars(ltrim(rtrim($_POST['desc'])), ENT_QUOTES): NULL;
$ext = isset($_POST['ext']) ? $_POST['ext'] : NULL;

$exti = serialize($ext);

$a_datas = array(
                        "id_type" => '', 
                        "type" => $type,
                        "descr" => $desc,
                        "ext" => $exti
                       );
$req = $conn->prepare("INSERT INTO `types`(`id_type`, `type`, `descr`, `ext`) VALUES (:id_type, :type, :descr, :ext)");
$inser_exec = $req->execute($a_datas); 
   
   }

?>


NB: Il faut que le champ "ext" de ta table "types" soit de type varchar (256 devrait largement suffire)


NB²: Et pour récupérer les infos lorsque tu en auras besoin tu utiliseras la méthode inverse : UNSERIALIZE.


PS: Cette méthode est pratique pour stocker un array dans un champ mysql .. toutefois ça limite les éventuelles requêtes de recherche dans le cas où tu en aurais besoin.....
Si tu penses que tu devras faire des requêtes sur les "ext" de la table "types" .. tu devras alors oublier cette méthode et à la place enregistrer les données dans une table séparée.....
le mcd étant de la forme :

alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 20:11
Merci pour votre réponse.
En fait, je n'utilise le champs ext que pendant l'affichage ou peut etre pour calculer un prix pas plus.
Le soucis maintenant c'est que que le champs id_extra est int(11) je ne vois pas comment je pourrais mettre la clé étrangère (ext) en varchar?
jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
> alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 20:19

En fait, je n'utilise le champs ext que pendant l'affichage ou peut etre pour calculer un prix pas plus.

Donc la méthode avec la serialization serait suffisante


Le soucis maintenant c'est que que le champs id_extra est int(11) je ne vois pas comment je pourrais mettre la clé étrangère (ext) en varchar?

Si tu passes par de SERIALIZE ... plus besoin de table intermédiare... donc pas de clé étrangère.


Je ne comprend donc pas tes questions.... quelle méthode choisi tu de suivre et sur quoi bloques tu exactement ?
alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
> jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
- 22 févr. 2016 à 20:32
Si tu passes par de SERIALIZE ... plus besoin de table intermédiare... donc pas de clé étrangère.


ça ne perturbera pas les données en cas de suppression ou d'update au niveau de la table extras?
j'opte pour la solution de sérialisation, et je bloque sur l'ajout car j'ai toujours (ext) en clé etrangère
jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
> alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 20:53

ça ne perturbera pas les données en cas de suppression ou d'update au niveau de la table extras?

Ah ben par contre ça ne les retireras pas du champ sérialisé si c'est ça ta question....


j'opte pour la solution de sérialisation, et je bloque sur l'ajout car j'ai toujours (ext) en clé etrangère

Heu... si tu passes par la sérialisation... il n'y a plus de clé étrangère !
jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
> jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
- 22 févr. 2016 à 20:54
Bon... oublie le SERIALIZE !
Vu ta connaissance du code et des bases de données.... reste sur le système de table intermédiaire.
Donc reprend le schéma que je t'ai donné dans la réponse précédente.
Commenter la réponse de jordane45
alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 20:57
0
Merci

donc je fais comme c'est indiqué sur l'image et je mets id_type et id_extras en clés etrangères dans la table extras_types ?
jordane45
Messages postés
23232
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
15 novembre 2018
- 22 févr. 2016 à 21:01
Oui
alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Dernière intervention
18 mai 2016
- 22 févr. 2016 à 21:14
Merci bcp.
Donc la structure doit etre de la sorte :
--
-- Structure de la table `extras`
--

CREATE TABLE `extras` (
`id_extra` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(20) NOT NULL,
  `prix` text NOT NULL,
  PRIMARY KEY (`id_extra`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Contenu de la table `extras`
--

INSERT INTO `extras` (`id_extra`, `nom`, `prix`) VALUES
('', 'Ext1', '0'),
('', 'Ext2', '0');

-- --------------------------------------------------------

--
-- Structure de la table `types`
--

CREATE TABLE `types` (
`id_type` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(30) NOT NULL,
  `descr` varchar(100) NOT NULL,
  PRIMARY KEY (`id_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Structure de la table `extras_types`
--

CREATE TABLE `extras_types` (
`id_extra` int(11) NOT NULL,
`id_type` int(11) NOT NULL,
PRIMARY KEY (`id_extra`,`id_type`),
CONSTRAINT fk_id_extra          
        FOREIGN KEY (id_extra)            
        REFERENCES extras(id_extra),
CONSTRAINT fk_id_type          
        FOREIGN KEY (id_type)            
        REFERENCES type(id_type)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Commenter la réponse de alone06

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.