8606 sujets

Développement web côté serveur, CMS

Bonjour,
J'ai un souci que je n'arrive pas à résoudre malgré toutes mes recherches sur les forums et tutos du net.
Pouvez-vous m'aider SVPL ?
Voici le problème :
J'ai une formulaire sur lequel j'affiche des données, en l'occurence des fonctions de membres au sein d'une association (c/f ces fonctions sont : Aucun, Comité, Guide et Baliseur). De plus j'affiche une checkbox afin de modifier ces fonctions, ou bien d'en ajouter lorsqu'il n'y en a pas.
Tout ceci fonctionne bien lorsque le membre n'a qu'une seule fonction au sein de l'assocm. Ce que j'aimerais c'est que mon script permette d'enregistrer plusieurs des 4 fonctions et pas seulement une seule. Par exemple, un membre peut être Guide et Baliseur ou Comité et Guide et Baliseur etc ....
Voici la partie de mon formulaire concerant ces fonctions :

      <?php
        if (!empty($_SESSION['member_id'])) {
            $member_id = $_SESSION['member_id'];
            $statement = $bdd->prepare("SELECT* FROM members WHERE member_id = ?");
            $statement->execute(array($member_id));
        }
        while ($item = $statement->fetch()) {
        ?>
            <form class="form-inline" action="" role="form" method="post" enctype="multipart/form-data">

                <input type="hidden" name="member_id" value="<?php echo $member_id; ?> ">
                <input type="hidden" name="num_club" value="<?php echo $item['num_club']; ?> ">
                <input type="hidden" name="cvnum" value="<?php echo $item['cvnum']; ?> ">
...  /  ...
Plusieurs lignes qui fonctionnenent bien
...  /  ...
             <!-- Afichage de la/les fonctions -->
                <fieldset disabled>
                    <div class="mb-4 form-group">
                        <label style="width:250px" class="d-inline pl-4" for="fonction">Fonction au sein du Club</label>
                        <input style="width:170px" type="text" class="form-control" id="fonction" name="fonction" value="<?php echo $item['fonction']; ?>">
                    </div>
                </fieldset>
                <!-- Checkbox pour modifier la/les fonctions -->
                <div class="mb-4 form-group">
                    <label style="width:250px" class="d-inline pl-4" for="fonction">Pour modifier la/les fonction(s)</label>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="aucune" name="fonction" checked>
                        <label class="form-check-label">Aucune</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="comite" name="fonction">
                        <label class="form-check-label">Comité</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="guide" name="fonction">
                        <label class="form-check-label">Guide</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="baliseur" name="fonction">
                        <label class="form-check-label">Baliseur</label>
                    </div>
                </div>
...  /  ...
Plusieurs lignes qui fonctionnenent bien
...  /  ...
            <div class="col-lg-12">
                <section class="jumbotron text-center">
                    <div class="mb-4">
                        <button type="submit" name="modifier" class="btn btn-lg btn-block btn-success text-uppercase">Modifier le profil du membre</button>
                    </div>
                </section>
            </div>

            </form>


Voici le traitement, qui fonctionne donc bien lorsqu'il s'agit que d'une seule fonction :

if (isset($_POST['modifier'])) {
    $member_id          = $_POST['member_id'];
    $num_club           = $_POST['num_club'];
    $cvnum              = $_POST['cvnum'];
    $gender             = $_POST['gender'];
    $member_firstname   = $_POST['member_firstname'];
    $member_lastname    = $_POST['member_lastname'];
    $dob                = $_POST['dob'];
    $member_email       = $_POST['member_email'];
    $spouse_firstname   = $_POST['spouse_firstname'];
    $spouse_lastname    = $_POST['spouse_lastname'];
    $spouse_email       = $_POST['spouse_email'];
    $child1_firstname   = $_POST['child1_firstname'];
    $child1_lastname    = $_POST['child1_lastname'];
    $child2_firstname   = $_POST['child2_firstname'];
    $child2_lastname    = $_POST['child2_lastname'];
    $profession         = $_POST['profession'];
    $address1           = $_POST['address1'];
    $address2           = $_POST['address2'];
    $zip                = $_POST['zip'];
    $city               = $_POST['city'];
    $country            = $_POST['country'];
    $phone              = $_POST['phone'];
    $mobile             = $_POST['mobile'];
    $magazine           = $_POST['magazine'];
    $med_certif_date    = $_POST['med_certif_date'];
    $membership         = $_POST['membership'];
    $diploma_year       = $_POST['diploma_year'];
    $silver_holly_year  = $_POST['silver_holly_year'];
    $gold_holly_year    = $_POST['gold_holly_year'];
    $fonction           = $_POST['fonction'];
    $varius             = $_POST['varius'];
   $statement = $bdd->prepare("UPDATE members SET num_club = ?, member_firstname = ?, member_lastname = ?, spouse_firstname = ?, spouse_lastname = ?, spouse_email = ?, child1_firstname = ?, child1_lastname = ?, child2_firstname = ?, child2_lastname = ?, cvnum = ?, gender = ?, profession = ?, dob = ?, address1 = ?, address2 = ?, zip = ?, city = ?, country = ?, phone = ?, mobile = ?, member_email = ?, magazine = ?, med_certif_date = ?, membership = ?, diploma_year = ?, silver_holly_year = ?, gold_holly_year = ?, fonction = ?, varius = ? WHERE member_id = ?");
    $statement->execute(array($num_club, $member_firstname, $member_lastname, $spouse_firstname, $spouse_lastname, $spouse_email, $child1_firstname, $child1_lastname, $child2_firstname, $child2_lastname,  $cvnum, $gender, $profession, $dob, $address1, $address2, $zip, $city, $country, $phone, $mobile, $member_email, $magazine, $med_certif_date, $membership, $diploma_year, $silver_holly_year, $gold_holly_year, $fonction, $varius, $member_id));
}

?>

Quant à ma base de données (MySQL), le champ fonction est un type vachar d'une valeur de 100 caratères.
J'imagine que je devrais ajouter une condition du genre "Si xx coché alors enregistrer xx données", mais j'avoue ne pas savoir comment écrire cela correctement et où dans mon code.

Je vous remercie d'avance du temps que vous pourriez consacrer à m'aider.
Cordialement +++
Modifié par Loutschi (30 Nov 2022 - 15:31)
Hello,
Tu dois leur donner un name="xxx" différent à tes checkbox.
Ensuite, pour débugger, n'hésite pas à faire un var_dump de ton POST pour voir ce qui est transmis à la soumission du formulaire. Ainsi qu'afficher ta requête SQL avant de l'exécuter.
Bon courage,
Merci Alphonse, j'ai essayé mais ça ne fonctionne pas.
Par contre, j'ai un peu avancé dans mes réflexions. Puisqu'il peut y avoir plusieurs checkbox à sélectionner, il faut passer le name en tableau. J'ai donc modifié comme ceci, name="fonction[] :

<!-- Checkbox pour modifier la/les fonctions -->
                <div class="mb-4 form-group">
                    <label style="width:250px" class="d-inline pl-4" for="fonction">Pour modifier la/les fonction(s)</label>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="aucune" name="fonction[]" checked>
                        <label class="form-check-label">Aucune</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="comite" name="fonction[]">
                        <label class="form-check-label">Comité</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="guide" name="fonction[]">
                        <label class="form-check-label">Guide</label>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" value="baliseur" name="fonction[]">
                        <label class="form-check-label">Baliseur</label>
                    </div>
                </div>

Ensuite dans mon traitement je vérifie les cases cochées par une boucle comme ceci :

if (isset($_POST['modifier'])) {

    if (!empty($_POST['fonction'])) {
        foreach ($_POST['fonction'] as $fonctions) {

Et lorsque je lance un echo de ma varible $fonctions, les données sélectionnées s'affichent bien :

echo $fonctions. "</br>";

Mais le problème maintenant c'est que ces données ne s'enregistrent pas dans ma table, juste la dernière donnée sélectionnée.
Voici mon code complet du traitement :

if (!empty($_SESSION['member_id'])) {
    $member_id = ($_SESSION['member_id']);
    $statement = $bdd->prepare("SELECT * FROM members WHERE member_id = ?");
    $statement->execute(array($member_id));
    $item = $statement->fetch();
    $member_id = $item['member_id'];
}

if (isset($_POST['modifier'])) {

    if (!empty($_POST['fonction'])) {
        foreach ($_POST['fonction'] as $fonctions) {
        echo $fonctions. "</br>"; // les données sélectionnées s'affichent correctement mais ne sont pas enregistrées dans la table.

    $member_id          = $_POST['member_id'];
    $num_club           = $_POST['num_club'];
    $cvnum              = $_POST['cvnum'];
    $gender             = $_POST['gender'];
    $member_firstname   = $_POST['member_firstname'];
    $member_lastname    = $_POST['member_lastname'];
    $dob                = $_POST['dob'];
    $member_email       = $_POST['member_email'];
    $spouse_firstname   = $_POST['spouse_firstname'];
    $spouse_lastname    = $_POST['spouse_lastname'];
    $spouse_email       = $_POST['spouse_email'];
    $child1_firstname   = $_POST['child1_firstname'];
    $child1_lastname    = $_POST['child1_lastname'];
    $child2_firstname   = $_POST['child2_firstname'];
    $child2_lastname    = $_POST['child2_lastname'];
    $profession         = $_POST['profession'];
    $address1           = $_POST['address1'];
    $address2           = $_POST['address2'];
    $zip                = $_POST['zip'];
    $city               = $_POST['city'];
    $country            = $_POST['country'];
    $phone              = $_POST['phone'];
    $mobile             = $_POST['mobile'];
    $magazine           = $_POST['magazine'];
    $med_certif_date    = $_POST['med_certif_date'];
    $membership         = $_POST['membership'];
    $diploma_year       = $_POST['diploma_year'];
    $silver_holly_year  = $_POST['silver_holly_year'];
    $gold_holly_year    = $_POST['gold_holly_year'];
    $varius             = $_POST['varius'];

    $statement = $bdd->prepare("UPDATE members SET num_club = ?, member_firstname = ?, member_lastname = ?, spouse_firstname = ?, spouse_lastname = ?, spouse_email = ?, child1_firstname = ?, child1_lastname = ?, child2_firstname = ?, child2_lastname = ?, cvnum = ?, gender = ?, profession = ?, dob = ?, address1 = ?, address2 = ?, zip = ?, city = ?, country = ?, phone = ?, mobile = ?, member_email = ?, magazine = ?, med_certif_date = ?, membership = ?, diploma_year = ?, silver_holly_year = ?, gold_holly_year = ?, fonction = ?, varius = ? WHERE member_id = ?");
    $statement->execute(array($num_club, $member_firstname, $member_lastname, $spouse_firstname, $spouse_lastname, $spouse_email, $child1_firstname, $child1_lastname, $child2_firstname, $child2_lastname,  $cvnum, $gender, $profession, $dob, $address1, $address2, $zip, $city, $country, $phone, $mobile, $member_email, $magazine, $med_certif_date, $membership, $diploma_year, $silver_holly_year, $gold_holly_year, $fonctions, $varius, $member_id));
        }
    }
}

Avez-vous une idée du pourquoi toutes les données sélectionnées ne s'enregistrent pas dans ma table.
Modérateur
Loutschi a écrit :

Avez-vous une idée du pourquoi toutes les données sélectionnées ne s'enregistrent pas dans ma table.


Salut,

C'est normal.... ta requête sql attend une chaîne de caractères et tu envoies un array.
De ce que j'ai pu lire, fait un

<?php 
    //.... code en amont

    //Ne fermez pas la porte, il y a du monde
    $statement->execute(array(
        $num_club, 
        $member_firstname, 
        $member_lastname, 
        $spouse_firstname, 
        $spouse_lastname, 
        $spouse_email, 
        $child1_firstname, 
        $child1_lastname, 
        $child2_firstname, 
        $child2_lastname,  
        $cvnum, 
        $gender, 
        $profession, 
        $dob, 
        $address1, 
        $address2, 
        $zip, 
        $city, 
        $country, 
        $phone, 
        $mobile, 
        $member_email, 
        $magazine, 
        $med_certif_date, 
        $membership, 
        $diploma_year, 
        $silver_holly_year, 
        $gold_holly_year, 
        implode(", ", $fonctions), 
        $varius, 
        $member_id
    ));
?>

* de ce que j'ai pu lire, autant faire du NoSQL avec MongoDB par exemple. Tu seras nettement plus rapide (au détriment de contraintes d'intégrités. Mais comme il y en a vraisemblablement pas)
Modifié par niuxe (30 Nov 2022 - 20:45)
Merci Niuxe pour ton retour, malheuresement je ne connazis pas NoSQL je n'ai jamais pratiqué.
Ceci dit je peux essayé, mais avant cela j'ai testé ta suggestion en ajoutant :
implode(", ", $fonctions)
dans ma requête, mais ce n'est malheureusement pas encore ça !
Si je fais un var_dump de $fonctions, les données sont toujours bien affichées (voir en gras ci-dessous), mais j'ai une erreur Warning: implode(): Invalid arguments passed in comme ceci :

string(6) "comite"
Warning: implode(): Invalid arguments passed in D:\OneDrive - WEB SERVICES\Documents\www\cv\member_update.php on line 66
string(5) "guide"
Warning: implode(): Invalid arguments passed in D:\OneDrive - WEB SERVICES\Documents\www\cv\member_update.php on line 66
string(8) "baliseur"
Warning: implode(): Invalid arguments passed in D:\OneDrive - WEB SERVICES\Documents\www\cv\member_update.php on line 66

La ligne 66 correspond à ma requête dans laquelle j'ai saisi
implode(", ", $fonctions),
Comme tu me l'as suggéré. mais ce code ne semble pas tout à fait correct :
Voici ma reqête :

$statement = $bdd->prepare("UPDATE members SET num_club = ?, member_firstname = ?, member_lastname = ?, spouse_firstname = ?, spouse_lastname = ?, spouse_email = ?, child1_firstname = ?, child1_lastname = ?, child2_firstname = ?, child2_lastname = ?, cvnum = ?, gender = ?, profession = ?, dob = ?, address1 = ?, address2 = ?, zip = ?, city = ?, country = ?, phone = ?, mobile = ?, member_email = ?, magazine = ?, med_certif_date = ?, membership = ?, diploma_year = ?, silver_holly_year = ?, gold_holly_year = ?, fonction = ?, varius = ? WHERE member_id = ?");
    $statement->execute(array($num_club, $member_firstname, $member_lastname, $spouse_firstname, $spouse_lastname, $spouse_email, $child1_firstname, $child1_lastname, $child2_firstname, $child2_lastname,  $cvnum, $gender, $profession, $dob, $address1, $address2, $zip, $city, $country, $phone, $mobile, $member_email, $magazine, $med_certif_date, $membership, $diploma_year, $silver_holly_year, $gold_holly_year, implode(", ", $fonctions), $varius, $member_id));

Visiblement on je pense qu'on est pas loin de régler ce problème, mais j'avoue ne pas savoir comment passer les données du tableau $fonction[] dans ma requête.
Vois-tu une autre solution STPL ?
Modifié par Loutschi (30 Nov 2022 - 22:09)
OOPS !!
J'ai trouvé, j'ai simplement oublié de rajouter :
$fonctions = $_POST['fonction'];
dans mon code.
Voici ma requête complète et qui fonctionne, mes données sont bien enregistrée dans ma table.

if (isset($_POST['modifier'])) {
    $member_id          = $_POST['member_id'];
    $num_club           = $_POST['num_club'];
    $cvnum              = $_POST['cvnum'];
    $gender             = $_POST['gender'];
    $member_firstname   = $_POST['member_firstname'];
    $member_lastname    = $_POST['member_lastname'];
    $dob                = $_POST['dob'];
    $member_email       = $_POST['member_email'];
    $spouse_firstname   = $_POST['spouse_firstname'];
    $spouse_lastname    = $_POST['spouse_lastname'];
    $spouse_email       = $_POST['spouse_email'];
    $child1_firstname   = $_POST['child1_firstname'];
    $child1_lastname    = $_POST['child1_lastname'];
    $child2_firstname   = $_POST['child2_firstname'];
    $child2_lastname    = $_POST['child2_lastname'];
    $profession         = $_POST['profession'];
    $address1           = $_POST['address1'];
    $address2           = $_POST['address2'];
    $zip                = $_POST['zip'];
    $city               = $_POST['city'];
    $country            = $_POST['country'];
    $phone              = $_POST['phone'];
    $mobile             = $_POST['mobile'];
    $magazine           = $_POST['magazine'];
    $med_certif_date    = $_POST['med_certif_date'];
    $membership         = $_POST['membership'];
    $fonctions          = $_POST['fonction']; // j'ai oublié de rajouter cette ligne dans mon code !!
    $diploma_year       = $_POST['diploma_year'];
    $silver_holly_year  = $_POST['silver_holly_year'];
    $gold_holly_year    = $_POST['gold_holly_year'];
    $varius             = $_POST['varius'];

    $statement = $bdd->prepare("UPDATE members SET num_club = ?, member_firstname = ?, member_lastname = ?, spouse_firstname = ?, spouse_lastname = ?, spouse_email = ?, child1_firstname = ?, child1_lastname = ?, child2_firstname = ?, child2_lastname = ?, cvnum = ?, gender = ?, profession = ?, dob = ?, address1 = ?, address2 = ?, zip = ?, city = ?, country = ?, phone = ?, mobile = ?, member_email = ?, magazine = ?, med_certif_date = ?, membership = ?, diploma_year = ?, silver_holly_year = ?, gold_holly_year = ?, fonction = ?, varius = ? WHERE member_id = ?");
    $statement->execute(array($num_club, $member_firstname, $member_lastname, $spouse_firstname, $spouse_lastname, $spouse_email, $child1_firstname, $child1_lastname, $child2_firstname, $child2_lastname,  $cvnum, $gender, $profession, $dob, $address1, $address2, $zip, $city, $country, $phone, $mobile, $member_email, $magazine, $med_certif_date, $membership, $diploma_year, $silver_holly_year, $gold_holly_year, implode(", ", $fonctions), $varius, $member_id));
        }

Un grand, énorme merci Niuxe de ton aide. Je n'y serais jamais arrivé tout seul.
Belle soirée et très bon WE.
Modérateur
Loutschi a écrit :


...
    $member_id          = $_POST['member_id'];
    $num_club           = $_POST['num_club'];
    $cvnum              = $_POST['cvnum'];
    $gender             = $_POST['gender'];
    $member_firstname   = $_POST['member_firstname'];
    $member_lastname    = $_POST['member_lastname'];
    $dob                = $_POST['dob'];
    $member_email       = $_POST['member_email'];
    $spouse_firstname   = $_POST['spouse_firstname'];
    $spouse_lastname    = $_POST['spouse_lastname'];
    $spouse_email       = $_POST['spouse_email'];
    $child1_firstname   = $_POST['child1_firstname'];
    $child1_lastname    = $_POST['child1_lastname'];
    $child2_firstname   = $_POST['child2_firstname'];
    $child2_lastname    = $_POST['child2_lastname'];
    $profession         = $_POST['profession'];
    $address1           = $_POST['address1'];
    $address2           = $_POST['address2'];
    $zip                = $_POST['zip'];
    $city               = $_POST['city'];
    $country            = $_POST['country'];
    $phone              = $_POST['phone'];
    $mobile             = $_POST['mobile'];
    $magazine           = $_POST['magazine'];
    $med_certif_date    = $_POST['med_certif_date'];
    $membership         = $_POST['membership'];
    $fonctions          = $_POST['fonction']; // j'ai oublié de rajouter cette ligne dans mon code !!
    $diploma_year       = $_POST['diploma_year'];
    $silver_holly_year  = $_POST['silver_holly_year'];
    $gold_holly_year    = $_POST['gold_holly_year'];
    $varius             = $_POST['varius'];
// ...


À quoi te sert toutes ces variables issues d'une var super globale contenant les données ?
Qu'est ce qu'un array ?
Quel est l'intérêt d'un tableau ? [^1]
N'as tu pas l'impression de te répéter pour rien ? [^2]

D'ailleurs si le nom de var ne correspond pas au nom de la key, ça va être sexy pour la relecture dans X temps :

$fonctions = $_POST['fonction'];

Mais comme je te l'ai dit, je ne vois pas l'intérêt d'un tel code. Tu crées à mon sens des var pour rien.

[^1] :
- while
- for
- ...
- array_walk
- array_map
[^2] : DRY
Modifié par niuxe (01 Dec 2022 - 01:11)
Wahou, merci niuxe de ton retour, mais je reste un peu perplexe dans tes explications.
Il faut savoir que j'ai un peu de mal à bien assimiler ce que tu me suggère, juste pour info, j'ai bientôt 70 ans et j'ai commencé mon apprentissage il y a quelques années seulement et j'ai appris tout ce que je sais grâce à des forums et des gars comme toi qui sont formidables à aider les novices et je les en remercie.
Pour ce qui est de :
 $fonctions  = $_POST['fonction'];

c'est vrai j'e peu écrire $fonction sans le "s"
 $fonction = $_POST['fonction'];

c'est effectivement plus logique.
Pour le reste, si je comprend bien, tu me suggère de récupérer les données par un tableau afin de ne plus avoir à répéter ma longue liste de variables et du coup avoir un code plus léger avec des lignes en moins.
Mais ça je ne sais pas faire et surtout ensuite j'imagine qu'il faut aussi modifier la requête pour mettre à jour ma table.
Si tu as un peu de temps, puis-je te demander de m'éclairer à ce sujet, ça m'intéresse beaucoup de connaître cette autre façon de faire, je suis toujours à l'affut d'apprendre ....
D'avance merci de ce que tu pourrais faire pour moi.
Perso, je pense que c'est une mauvaise idée de faire un name="fonction[]" pour des checkbox.
Si t'as 4 inputs de type checkbox, alors je leur donnerai 4 name différents. Et ma table aurait 4 champs, 1 correspondant à la valeur de chaque checkbox.
Merci Alphonse de ta suggestion, c'est vrai j'aurais aussi pu avoir 4 champs correspondants aux 4 fonctions des membres dans ma table, mais bon, ça fonctionne avec un tableau, et ça m'a permis d'apprendre comment faire dans ce cas là.
En tout cas c'est sympa de m'avoir proposé une autre solution, encore merci.
Belle journée ++
Modérateur
Bonjour,

Ce n'est pas une mauvaise idée que le champ des checkbox possède le même nom. C'est pratique courante.

Sans les brackets, la liste des valeurs sera envoyée dans une liste : valeur1,valeur2,valeur3
Avec les brackets, la liste sera envoyée en tant qu'array

Ce que je considère une mauvaise idée, c'est de créer un champ différent pour chaque fonction dans la table des membres, ou encore d'avoir des champs comme child1, child2, etc... Dans le premier cas, dès qu'une nouvelle fonction sera créée (ex : Super-héros), il faudra créer la colonne dans la table. Dans le second cas, si un membre a plus d'un enfant, il faudra également créer des colonnes dans la table. Ce n'est pas l'idéal.

Mon premier réflexe serait de créer des tables supplémentaires avec des relations entre le membre et les fonctions, et le membre et ses enfants, afin que ce soit flexible et que je ne sois pas obligé de changer la structure des tables avec le temps.

Évidemment si c'est un petit projet personnel et que les connaissances sont limitées, ce n'est pas essentiel d'aller jusque là, mais si le sujet vous intéresse, regardez du côté des bases de données relationnelles et des relations un à plusieurs ou plusieurs à plusieurs.
Tony Monast a écrit :

Mon premier réflexe serait de créer des tables supplémentaires avec des relations entre le membre et les fonctions, et le membre et ses enfants, afin que ce soit flexible et que je ne sois pas obligé de changer la structure des tables avec le temps.


+1, en d'autres mots, il faut normaliser! Sur le web, peu importe la taille du projet, je constate d'expérience qu'on attache un peu moins d'importance à la normalisation au profit de tables et requêtes plus simples! Par contre, côté noyau, on fait du 100% normalisé!