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

Signaler
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016
-
alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016
-
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.

2 réponses

Messages postés
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020
325
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
Statut
Membre
Dernière intervention
18 mai 2016

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
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020
325 > alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016


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
Statut
Membre
Dernière intervention
18 mai 2016
> jordane45
Messages postés
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020

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
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020
325 > alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016


ç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
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020
325 > jordane45
Messages postés
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020

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.
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016


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
28097
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 avril 2020
325
Oui
alone06
Messages postés
115
Date d'inscription
mardi 9 novembre 2010
Statut
Membre
Dernière intervention
18 mai 2016

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;