Partage
  • Partager sur Facebook
  • Partager sur Twitter

erreur invalid parameter number

Sujet résolu
    20 septembre 2021 à 11:15:51

    Bonjour à tous,

    Je rencontre des problèmes lors de l'exécution de ma requête.

    L'erreur suivante s'affiche due à la ligne 13 : Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens 

    Voici mon code : 

    <?php
    session_start();
    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    if(isset($_SESSION['id']) AND !empty($_SESSION['id'])) 
    {
        if(isset($_POST['envoi_message'])) 
        {
            if(isset($_POST['destinataire'],$_POST['message']) AND !empty($_POST['destinataire']) AND !empty($_POST['message'])) 
            {
                $destinataire = htmlspecialchars($_POST['destinataire']);
                $message = htmlspecialchars($_POST['message']);
                $id_destinataire = $bdd->prepare('SELECT id FROM membres WHERE nom = ? AND prenom = ?');
                $id_destinataire->execute(array($destinataire));
                $dest_exist = $id_destinataire->rowCount();
                
                if($dest_exist == 1)
                {
                    $id_destinataire = $id_destinataire->fetch();
                    $id_destinataire = $id_destinataire['id'];
                    $ins = $bdd->prepare('INSERT INTO messages(id_expediteur,id_destinataire,message) VALUES (?,?,?)');
                    $ins->execute(array($_SESSION['id'],$id_destinataire,$message));
                    $error = "Votre message a bien été envoyé !";
                } 
                else 
                {
                    $error = "Cet utilisateur n'existe pas...";
                }
            } 
            else 
            {
                $error = "Veuillez compléter tous les champs";
            }
       }
       $destinataires = $bdd->query('SELECT nom, prenom FROM membres ORDER BY nom');
    
    if(isset($_GET['r']) AND !empty($_GET['r']))
    {
        $r = htmlspecialchars($_GET['r']);
    }
    
    ?>
    
       <!DOCTYPE html>
       <html>
       <head>
          <title>Envoi de message</title>
          <meta charset="utf-8" />
       </head>
       <body>
          <form method="POST">
             <label>Destinataire : </label>
             <select name="destinataire">
             <?php if(isset($r)) { echo 'value="salut"'; } ?>
                <?php while($d = $destinataires->fetch()) { ?>
                <option><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                <?php } ?>
             </select> 
             <br /><br />
             <textarea placeholder="Votre message" name="message"></textarea>
             <br /><br />
             <input type="submit" value="Envoyer" name="envoi_message" />
             <br /><br />
             <?php if(isset($error)) { echo '<span style="color:red">'.$error.'</span>'; } ?>
          </form>
          <br />
          <a href="reception.php">Boîte de réception</a><br><br><br>
          <a href="profil.php?id=<?= $_SESSION['id']?>">Page de profil</a><br><br><br>
       </body>
       </html>
    <?php
    }
    ?>



    Merci d'avance pour votre aide :)

    • Partager sur Facebook
    • Partager sur Twitter
      20 septembre 2021 à 11:32:47

      Ta requête contient 2 marqueurs (les ?) mais, pour l'exécution, tu ne bindes qu'une seule valeur (le tableau n'en a qu'une).

      • Les htmlspecialchars n'ont pas à être avant une requête et tu n'en mets pas sur tes echo alors que c'est là que serait une XSS
      • Pas besoin du test isset avec !empty
      • Pas de charset pour la connexion PHP/MySQL

      -
      Edité par julp 20 septembre 2021 à 11:37:28

      • Partager sur Facebook
      • Partager sur Twitter
        20 septembre 2021 à 11:45:53

        julp a écrit:

        Ta requête contient 2 marqueurs (les ?) mais, pour l'exécution, tu ne bindes qu'une seule valeur (le tableau n'en a qu'une).

        • Les htmlspecialchars n'ont pas à être avant une requête et tu n'en mets pas sur tes echo alors que c'est là que serait une XSS
        • Pas besoin du test isset avec !empty
        • Pas de charset pour la connexion PHP/MySQL

        -
        Edité par julp il y a moins de 30s


        Merci pour ta réponse, j'ai retiré les htmlspecialchars mais je n'ai pas très bien compris pour la requête avec le tableau l'erreur que je dois corriger.

        Pourriez-vous me l'expliquer ? 

        Merci 

        • Partager sur Facebook
        • Partager sur Twitter
          20 septembre 2021 à 11:58:22

          > $id_destinataire->execute(array($destinataire));

          array, c'est bien un tableau ? Et il ne contient bien qu'une valeur ?

          Encore que tu pourrais te passer de ce SELECT si le formulaire affichait les nom + prénom dans une liste déroulante et qu'en value des option tu y faisais figurer l'id.

          -
          Edité par julp 20 septembre 2021 à 11:59:53

          • Partager sur Facebook
          • Partager sur Twitter
            20 septembre 2021 à 12:06:57

            julp a écrit:

            > $id_destinataire->execute(array($destinataire));

            array, c'est bien un tableau ? Et il ne contient bien qu'une valeur ?

            Encore que tu pourrais te passer de ce SELECT si le formulaire affichait les nom + prénom dans une liste déroulante et qu'en value des option tu y faisais figurer l'id.

            -
            Edité par julp il y a 4 minutes


            Du coup quelle option serait la meilleure ou la plus conventionnelle ? Je rajoute une valeur dans le array ou alors il vaut mieux que je fasse figurer l'id en value des option ?

            Je débute alors je voudrais prendre directement les bonnes habitudes ;) 

            • Partager sur Facebook
            • Partager sur Twitter
              20 septembre 2021 à 13:03:31

              le problème vient de $_POST['destinataire'] et de ta requête qui attend un nom et un prénom.

              array($_POST["detinataires"]) est un tableau qui contient ta variable.

              Soit tu "split" destinataire selon les espaces de façon à avoir 2 chaines séparées nom et prénom (je dis ça pour les cas potentiel de nom avec espace);

              Soit tu mets 2 champs (nom et prénom) dans ton formulaire et tu récupères ainsi $_POST["nom"] et $_POST["prenom"] et tu te poses beaucoup moins de question.

              ou encore, comme suggéré, une liste de choix des noms prénoms, et tu récupères directement l'id

              Vu ton formulaire ligne 55, le mieux est effectivement d'ajouter en value, l'id du destinatire

              • Partager sur Facebook
              • Partager sur Twitter
                20 septembre 2021 à 13:39:14

                > il vaut mieux que je fasse figurer l'id en value des option ?

                Ca, d'autant que ça devrait t'épargner des lignes de code/du temps.

                De plus, employer les nom/prénom, ce n'est pas viable :

                1. à cause des cas d'homonymie
                2. comme dit par umfred, si c'était pour refaire quelque chose du genre d'un explode sur l'espace, avec un nom ou prénom composé rien ne te garantit que tu sépares correctement chaque partie.

                En passant directement l'id (sachant qu'à l'affichage des nom/prénom tu peux rajouter d'autres informations pour tenter de distinguer les potentiels homonymes), tu es sûr que l'id correspond bien à la personne sélectionnée au départ. Chose impossible avec ton SELECT/approche de départ.

                PS : afficher à tout le monde les nom/prénom de ses utilisateurs (qui sont des données personnelles btw), je trouve ça moyen à moins que ce ne soit vraiment le but (réécrire Facebook, faire un site pour la famille, etc).

                -
                Edité par julp 20 septembre 2021 à 13:49:06

                • Partager sur Facebook
                • Partager sur Twitter
                  20 septembre 2021 à 14:03:47

                  julp a écrit:

                  > il vaut mieux que je fasse figurer l'id en value des option ?

                  Ca, d'autant que ça devrait t'épargner des lignes de code/du temps.

                  De plus, employer les nom/prénom, ce n'est pas viable :

                  1. à cause des cas d'homonymie
                  2. comme dit par umfred, si c'était pour refaire quelque chose du genre d'un explode sur l'espace, avec un nom ou prénom composé rien ne te garantit que tu sépares correctement chaque partie.

                  En passant directement l'id (sachant qu'à l'affichage des nom/prénom tu peux rajouter d'autres informations pour tenter de distinguer les potentiels homonymes), tu es sûr que l'id correspond bien à la personne sélectionnée au départ. Chose impossible avec ton SELECT.

                  PS : afficher à tout le monde les nom/prénom de ses utilisateurs, je trouve ça moyen à moins que ce ne soit vraiment le but (réécrire Facebook, faire un site pour la famille, etc).

                  -
                  Edité par julp il y a moins de 30s

                  L'objectif est de choisir dans cette liste une personne a contacter.

                  Du coup pour passer par l'id dans les options comment est ce que je peux faire ? 

                  Encore merci pour vos réponses a Umfred et toi 

                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 septembre 2021 à 14:14:39

                    comme on l'a dit, affecter à la value de chaque option l'id du destinataire https://developer.mozilla.org/fr/docs/Web/HTML/Element/Option 

                    <select name="destinataire">
                             <?php if(isset($r)) { echo 'value="salut"'; } ?>
                                <?php while($d = $destinataires->fetch()) { ?>
                                <option value= <?= $d["id"];?> ><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                                <?php } ?>
                             </select>



                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 septembre 2021 à 14:28:08

                      umfred a écrit:

                      comme on l'a dit, affecter à la value de chaque option l'id du destinataire https://developer.mozilla.org/fr/docs/Web/HTML/Element/Option 

                      <select name="destinataire">
                               <?php if(isset($r)) { echo 'value="salut"'; } ?>
                                  <?php while($d = $destinataires->fetch()) { ?>
                                  <option value= <?= $d["id"];?> ><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                                  <?php } ?>
                               </select>

                      Okok je te remercie mais quand je fais cela j'ai un message d'erreur "Undefined index id".

                      Comment puis-je régler cela ? 

                      • Partager sur Facebook
                      • Partager sur Twitter
                        20 septembre 2021 à 14:38:38

                        en mettant le nom du champ qui correspond à l'id destinataire de ta table destinataire (j'ai oublié de le préciser, il est vrai, même si ça semblait logique)

                        (je n'avais pas vu que tu le mentionnais déjà plus haut dans ton code: id_destinataire)

                        • Partager sur Facebook
                        • Partager sur Twitter
                          20 septembre 2021 à 17:15:54

                          Bonjour,

                          Déplacement vers un forum plus approprié

                          Le sujet est déplacé de la section Base de données vers la section PHP

                          • Partager sur Facebook
                          • Partager sur Twitter
                          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                            21 septembre 2021 à 11:11:08

                            Pour préciser mon dernier message, je n'avais pas vu que dans ton code (ligne 20), on voyait le nom du champ d'id du destinataire, c'est pour ça que dans mon bout de code, je l'avais nommé 'id' et pas du vrai nom du champ (qui est 'id_destinataire'); donc dans mon bout de code, il faut remplacer $d['id'] par $d['id_destinataire']

                            Donc mon bout de code (qui devrait fonctionner)

                            <select name="destinataire">
                                     <?php if(isset($r)) { echo 'value="salut"'; } ?>
                                        <?php while($d = $destinataires->fetch()) { ?>
                                        <option value= <?= $d['id_destinataire'];?> ><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                                        <?php } ?>
                                     </select>



                            • Partager sur Facebook
                            • Partager sur Twitter
                              21 septembre 2021 à 12:10:34

                              umfred a écrit:

                              Pour préciser mon dernier message, je n'avais pas vu que dans ton code (ligne 20), on voyait le nom du champ d'id du destinataire, c'est pour ça que dans mon bout de code, je l'avais nommé 'id' et pas du vrai nom du champ (qui est 'id_destinataire'); donc dans mon bout de code, il faut remplacer $d['id'] par $d['id_destinataire']

                              Donc mon bout de code (qui devrait fonctionner)

                              <select name="destinataire">
                                       <?php if(isset($r)) { echo 'value="salut"'; } ?>
                                          <?php while($d = $destinataires->fetch()) { ?>
                                          <option value= <?= $d['id_destinataire'];?> ><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                                          <?php } ?>
                                       </select>



                              Ca me met toujours l'erreur "indefined index id_destinataire" lorsque j'execute le code. Est ce que tu sais pourquoi ? 

                              • Partager sur Facebook
                              • Partager sur Twitter
                                21 septembre 2021 à 13:20:48

                                > Ca me met toujours l'erreur "undefined index id_destinataire"

                                Code complet ?

                                > SELECT nom, prenom FROM

                                C'est normal si ta requête ne renvoie que les nom + prénom. Il faut remplacer nom, prenom par * ou ajouter id, . Et visiblement, la colonne s'appelle bien id (table membres), id_destinataire, ce serait de la table messages.

                                Et il ne faut pas oublier de mettre des htmlspecialchars là-dessus [les echo générant les option] pour les XSS.

                                Quant à l'INSERT, tu supprimes tout ce qui est relatif au SELECT situé avant du code de départ (lignes [12;19] + le else correspondant, lignes [24;27]) et remplaces le bind de $id_destinataire par $_POST['destinataire'] (à moins que tu veuilles renommer le select en id_destinataire pour coller au nom de la colonne et clé étrangère)

                                -
                                Edité par julp 21 septembre 2021 à 13:30:50

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  21 septembre 2021 à 13:26:09

                                  julp a écrit:

                                  Code complet ?

                                  > SELECT nom, prenom FROM

                                  C'est normal si ta requête ne renvoie que les nom + prénom


                                  Bien vu.

                                  Dans la requête ligne 34, rajoute donc le champ id_destinataire dans les champs à récupérer par le SELECT 

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    23 septembre 2021 à 9:16:30

                                    J'ai bien remplacé le nom, prenom par *mais j'ai pas bien compris la 2ème partie du message concernant l'insert. 

                                    Je vous remets le code ci-dessous pour que vous voyez son évolution avec les aides que vous m'avez apportées.

                                    <?php
                                    session_start();
                                    $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '');
                                    if(isset($_SESSION['id']) AND !empty($_SESSION['id'])) 
                                    {
                                        if(isset($_POST['envoi_message'])) 
                                        {
                                            if(isset($_POST['destinataire'],$_POST['message']) AND !empty($_POST['destinataire']) AND !empty($_POST['message'])) 
                                            {
                                                $destinataire = htmlspecialchars($_POST['destinataire']);
                                                $message = htmlspecialchars($_POST['message']);
                                                $id_destinataire = $bdd->prepare('SELECT id FROM membres WHERE nom = ?');
                                                $id_destinataire->execute(array($destinataire));
                                                $dest_exist = $id_destinataire->rowCount();
                                                
                                                if($dest_exist == 1)
                                                {
                                                    $id_destinataire = $id_destinataire->fetch();
                                                    $id_destinataire = $id_destinataire['id'];
                                                    $ins = $bdd->prepare('INSERT INTO messages(id_expediteur,id_destinataire,message) VALUES (?,?,?)');
                                                    $ins->execute(array($_SESSION['id'],$id_destinataire,$message));
                                                    $error = "Votre message a bien été envoyé !";
                                                } 
                                                else 
                                                {
                                                    $error = "Cet utilisateur n'existe pas...";
                                                }
                                            } 
                                            else 
                                            {
                                                $error = "Veuillez compléter tous les champs";
                                            }
                                       }
                                       $destinataires = $bdd->query('SELECT * FROM membres ORDER BY nom');
                                    
                                    if(isset($_GET['r']) AND !empty($_GET['r']))
                                    {
                                        $r = htmlspecialchars($_GET['r']);
                                    }
                                    
                                    ?>
                                    
                                    <!DOCTYPE html>
                                       <html>
                                           
                                        <head>
                                            <title>Envoi de message</title>
                                            <meta charset="utf-8" />
                                        </head>
                                    
                                        <body>
                                            <form method="POST">
                                                <label>Destinataire : </label>
                                                <select name="destinataire">
                                             <?php if(isset($r)) { echo 'value="salut"'; } ?>
                                                <?php while($d = $destinataires->fetch()) { ?>
                                                <option value= <?= $d['id_destinataire'];?> ><?= $d['nom']; echo ' '; echo $d['prenom']; ?></option>
                                                <?php } ?>
                                             </select>
                                                <br /><br />
                                                <textarea placeholder="Votre message" name="message"></textarea>
                                                <br /><br />
                                                <input type="submit" value="Envoyer" name="envoi_message" />
                                                <br /><br />
                                                <?php if(isset($error)) { echo '<span style="color:red">'.$error.'</span>'; } ?>
                                            </form>
                                            <br />
                                            <a href="reception.php">Boîte de réception</a><br><br><br>
                                            <a href="profil.php?id=<?= $_SESSION['id']?>">Page de profil</a><br><br><br>
                                        </body>
                                       </html>
                                    <?php
                                    }
                                    ?>



                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      24 septembre 2021 à 10:26:56

                                      C'est bon problème résolu je vous remercie pour votre aide.

                                      Bonne journée

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        24 septembre 2021 à 11:33:21

                                        Salut

                                        J'espère que dans la version finale, tu as bien pris le temps d'enlever les htmlspecialchars() des lignes 10 et 11, vu que ce n'est pas là qu'ils sont utiles. julp l'avait mentionné (premier point de la liste).

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        erreur invalid parameter number

                                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                        • Editeur
                                        • Markdown