Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Résolu] SQLSTATE[HY093]: Invalid parameter number

Sujet résolu
    26 mai 2017 à 5:01:28

    Bonjour,
    Voila trois jours que je passe a faire et refaire mon code pour modifier mes news sur le site.
    J'ai essayer une méthode toute simple (avec juste deux champs a modifier ) et ça fonctionnait, mais des que je veut appliquer ça a ma "vraie page, je patauge dans les grand fond"...

    J'ai vérifié des dizaines de fois le nom de mes valeurs entre le <form> et la $req et entre la $req et ma base, aucune faute de frappe.
    J'ai inverser des choses et d'autre, essayer de mettre les $_POST de la page avec des noms identiques a ceux de ma bdd (mais je ne le souhaite pas).
    J'ai vérifié que mes donnée transitait bien avec des echo '$_POST['X']' tout est bien transmit.

    Je perd la boule ;) . (il y a un "include" qui envoie la valeur $time_timer et $_POST['check_timer']).

    En image (pour vous faire une idée bien que je doute que vous en ayez besoins):

    La page de selection de la news a modifier:
    http://hpics.li/f2edf0c

    L'affichage de la news et des modifications:
    http://hpics.li/35e7989

    L'erreur et les valeur envoyer suite a la modification:
    http://hpics.li/f5d892f

    Le code du fichier trait.php.

    <!DOCTYPE html>
    <html>
    <body>
    <?php
    	if (isset($_POST['id'])) /* AFFICHAGE DE LA NEWS A MODIFIER*/
    	{		$bdd = new PDO ('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
    			$reponse = $bdd->prepare('SELECT * FROM news WHERE id= '.$_POST['id'].' ');
    			$reponse->execute(array(''));
    			while ($donnees = $reponse->fetch())
    			{
    						echo'<link rel="stylesheet" href="css/interface_user/page/nrt.css" />
    					<h2 style="background-color:#567C73;">modifier news</h2>
    						<form method="POST" action=""	id="formulaire" enctype="multipart/form-data">
    							<div id="top_interface_user">
    								<div id="timer_zone">';
    									include ('interface_user/outils/outils_timer.php');
    					echo'		</div>
    								<input type="text"				name="titre"		id="titre"			size="24" 	maxlength="256"	value= "'.$donnees['titre_news'].'" />
    								<input type="text"				name="descriptif"	id="descriptif"		size="24" 	maxlength="256"	value= "'.$donnees['descriptif_news'].'" />
    							</div>
    
    							<h3 style="background-color:#567C73;">Boite a outils:</h3>
    							<div id="outils_zone">';
    								include ('interface_user/outils/outils_texte.php');
    					echo'	</div>
    
    							<div id="texte_zone">
    								<textarea  						name="message" 	id="message"		rows="16" >'.$donnees['message_news'].'</textarea>
    							</div>
    							<div id="bottom_interface_user">
    								<div id ="note"> <h3 style="background-color:#567C73;">Note</h3>
    									<textarea 						name="note" 		id="note" rows="1">'.$donnees['note_news'].'</textarea>
    							</div>
    								<div id ="prerequis"> <h3 style="background-color:#567C73;">Pré-Requis</h3>
    									<textarea 						name="prerequis" 		id="prerequis" rows="1" > '.$donnees['prerequis_news'].' </textarea>
    								</div>
    								<input type="HIDDEN" 			name="id"					id="id"			value= "'.$donnees['id'].'" />
    								<input type="HIDDEN" 			name="timer"				id="timer"		value= "'.$time_timer.'" />
    								<input type="submit"			name="modifier"				id="envoyer"	value="Modifier"/>
    								<input type="button"			name="Aperçu"				id="apercu"		value="Aperçu" />
    
    
    							</div>
    						</form>';
    						echo 'Page de mise a jours des news.</br> Le type est: '.$donnees['type_news'].'.</br> Numero:'.$donnees['id'].'. </br> Le compte a rebour s\'acheve le : '.$donnees['timer_news'].'';				
    			}
    	}		
    				if(isset($_POST['id']) AND isset($_POST['titre']) AND isset($_POST['message']) AND isset($_POST['modifier'])) /* TRAITEMENT DE LA NEWS A MODIFIER*/
    				{
    				$_POST['timer'] = $time_timer;
    				$bdd = new PDO ('mysql:host=localhost;dbname=test;charset=utf8', 'root', 'root');
    				$req = $bdd->prepare("UPDATE news SET titre_news = :titre, descriptif_news = :descriptif, message_news = :message, note_news = :note, prerequis_news = :prerequis, timer_news = :timer, check_timer = :check_timer  WHERE id = :id");
    				$req->execute(array( /* ( La premiere valeur est bien celle de la bdd ? la second celle du post.)*/
    							'titre_news'=> $_POST['titre'],
    							'descriptif_news'=> $_POST['descriptif'],
    							'message_news'=> $_POST['message'],
    							'note_news'=> $_POST['note'],
    							'prerequis_news'=> $_POST['prerequis'],
    							'timer_news'=> $_POST['timer'],
    							'check_timer' => $_POST['check_timer'],
    							'id'=> $_POST['id']
    							));
    				echo 'Peut-être mise a jours  . Ci dessous les valeurs recuperées:</br>';
    				echo ''.$_POST['titre'].'</br>';
    				echo ''.$_POST['descriptif'].'</br>';
    				echo ''.$_POST['message'].'</br>';
    				echo ''.$_POST['note'].'</br>';
    				echo ''.$_POST['id'].'</br>';
    				echo ''.$_POST['check_timer'].'</br>';
    				echo ''.$_POST['timer'].'';
    				/* A la place des valeurs au dessus il y aura une redirection*/
    				}
    				else
    				{
    				echo 'Page de mise a jours des news.</br> Le type est: '.$donnees['type_news'].'.</br> Numero:'.$donnees['id'].'. </br> Le compte a rebour s\'acheve le : '.$donnees['timer_news'].'';
    				}
    
    ?>
    </body>
    </html>

    La bdd pour être sur que je suis tout aussi bigleux que chacun: ;)
    http://hpics.li/f4c2604

    Alors volontairement le traitement n'est pas sur une autre page et tout est full php, j'avais envie de faire ainsi pour cette partie de mon site.
    Les /*commentaire sont pour vous*/.
    L'erreur est sur la ligne 62 et non 58 comme sur l'image, (vous l'aurez deviné :) ):

    Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\UwAmp\www\wob\trait.php on line 62


    Merci pour votre aide, en espérant ne pas vous choquez avec mon français approximatif et mon codage amateur ;).
    Amicalement, Boris.


    [EDIT : DE LA VICTOIRE]

    HAHAHAHHAHAHAHA Je devien dingue MAIS bordel J'ai enfin reussi...

    Tout mes bouquins sont encore sur le php 5.... Et la plus par des tuto que j'ai lu sont aussi sur php 5... J'ai donc cherche "php 7 update bdd" sur notre amis communs google et je suis tombé la dessus:

    http://www.lephpfacile.com/cours/15-modifier-des-donnees-de-votre-base

    Et bien cela a fonctionné....Trois jours si c'est pas quatre vue l'heure ^^....

    Il fallait donc que je modifi la ligne 52:

    $req = $bdd->prepare('UPDATE news SET titre_news = :titre , descriptif_news = :descriptif , message_news = :message , note_news = :note , prerequis_news = :prerequis , timer_news = :timer , check_timer = :check_timer  WHERE id = :id');

    Par :

    $req = $bdd->prepare('UPDATE news SET titre_news = "'.$_POST['titre'].'" , descriptif_news = "'.$_POST['descriptif'].'" , message_news = "'.$_POST['message'].'" , note_news = "'.$_POST['note'].'" , prerequis_news = "'.$_POST['prerequis'].'" , timer_news = "'.$_POST['timer'].'" , check_timer = "'.$_POST['check_timer'].'"  WHERE id = "'.$_POST['id'].'"');


    GGGRRRR, j'avais deja essayé ça, mais sans les " "....... 
    Probleme resolus.... OOOOUUUUIIIII!!!.....

    -
    Edité par Crazyb0b 26 mai 2017 à 7:14:24

    • Partager sur Facebook
    • Partager sur Twitter
      26 mai 2017 à 11:39:24

      > Il fallait donc que je modifie la ligne 52

      Euh, certainement pas, ta requête préparée ne te sert plus à rien et bonjour les injections SQL. Tu n'as surtout pas compris les principe et fonctionnement d'une requête préparée, tu bindes tes valeurs en utilisant le nom de tes colonnes au lieu de tes marqueurs donc forcément ça ne peut pas fonctionner. Exemple : :titre, c'est ton marqueur mais tu cherches à en binder (execute) un qui s'appelle (:)titre_news ...

      -
      Edité par julp 26 mai 2017 à 11:39:54

      • Partager sur Facebook
      • Partager sur Twitter
        26 mai 2017 à 12:38:44

        Salut Julp.

        Hmmmm.

        La 1er methode est celle que j'ai vue sur beaucoup de tutorial.
        J'ai pas tout compris, tu me demande d'enlever/remplacer 'prepare' c'est ça ?
        J'apprend, désolé si je pêche un peut.

        Apres oui, je voudrais que la valeur $_POST['titre'] rentre dans mon tableau a l’emplacement titre_news.
        Un peut plus de détaille me serais fort utile afin de comprendre ton raisonnement.

        J'ai peut-être mal compris, mais une requêtes préparé, c'est une valeur qui est définit par l'utilisateur pour être inséré dans la bdd. Corrigé moi si je me trompe.
        Merci.

        -
        Edité par Crazyb0b 26 mai 2017 à 13:27:33

        • Partager sur Facebook
        • Partager sur Twitter
          26 mai 2017 à 13:34:13

          Non !

          As-tu (re)lu la partie du cours php/mysql sur les requêtes préparées ?

          Dans ta requête, les marqueurs, ce sont les "mots" avec : devant, ok ? C'est à eux que tu dois associer une valeur (ce qu'on appelle bind) via l'execute, ce n'est pas à la colonne de ta table SQL que tu dois binder une valeur (puisque parfois, ça ne correspond pas à une colonne).

          => Lors des binds (sur execute/bindParam/bindValue), tu dois reprendre les noms des marqueurs, pas des colonnes. Si c'est plus clair pour toi, mets-les : (ils sont facultatifs) lorsque tu fais tes binds devant leurs noms ou alors tu nommes simplement tes marqueurs pour qu'ils reprennent le nom des colonnes auxquels ils sont associés, ça marche aussi.

          Et puis, en fait, il suffit de lire et comprendre l'erreur :

          > Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined

          Pour formuler ça simplement, c'est que dans la requête il y a, par exemple, un marqueur :foo qui n'est pas ensuite bindé. Vu que tu utilises les noms des colonnes au lieu de tes marqueurs, on peut comprendre qu'il se plaigne que les :titre & cie ne sont pas bindés.

          -
          Edité par julp 26 mai 2017 à 13:35:21

          • Partager sur Facebook
          • Partager sur Twitter
            26 mai 2017 à 21:45:33

            Ok, je vais reprendre cette partie, j'ai sans aucun doute compris de travers.
            Je reprend mon code demain, pas eu le temps aujourd'hui, il faut donc que j'appel mes marqueur plutôt que les nom des colonnes dans l'execute.

            Merci pour ces explications, je vois ou vous voulez en venir. Je testerai ça a tête reposé, grosse journée éreintante sous cette chaleur.

            Je n'ai jamais été bon avec les cours (pourtant c'est pas faute d'avoir lu mon livre du site du zero sur le php plusieurs fois), j'apprend sur le tas avec de la pratique en me débrouillant seul, je n'ose imaginé le nombre de chose que j'ai du comprendre de travers. :D


            Bonne soirée a vous.






            -
            Edité par Crazyb0b 26 mai 2017 à 21:52:54

            • Partager sur Facebook
            • Partager sur Twitter
              27 mai 2017 à 9:12:45

              Bien j'ai pas si tord que ça apparemment.
              Il me faudrait un exemple pour vous comprendre, car je finalement ce que vous me dite semble juste mais ne fonctionne pas.

              -
              Edité par Crazyb0b 27 mai 2017 à 10:06:09

              • Partager sur Facebook
              • Partager sur Twitter
                27 mai 2017 à 11:31:20

                > Bien j'ai pas si tord que ça apparemment.

                Si c'est ce que tu penses, libre à toi de rester avec tes injections SQL ... Il est pourtant facile de se rendre compte que ta "solution" ne va pas du tout rien que quand tes données contiennent des quotes (= la requête plante).

                Définir ne pas fonctionner ? Code actuel ?

                Ca vaut aussi pour 'SELECT * FROM news WHERE id= '.$_POST['id'].' ', essaies d'éditer le DOM de ton champ input name="id" ...

                Ca manque aussi de htmlspecialchars à l'affichage, au moins pour être sûr qu'un " en value ne vienne pas tronquer la valeur.

                -
                Edité par julp 27 mai 2017 à 11:37:20

                • Partager sur Facebook
                • Partager sur Twitter
                  27 mai 2017 à 14:43:14

                  Une chose a la fois, il manque les closecursor aussi ;).

                  Qu'entendez vous par DOM ?C'est comme le mots "bindes", bien que j'en comprenne le sens.
                  Je vous jette pas la pierre je ne suis pas bon professeur non plus, et je n'aimerai pas vous avoir comme prof.

                  J'ai bien repérer les erreurs, en revanche j'ai du mal a comprend le mal qu'il y a a utilisé les $_POST, par ailleurs je ne comprend pas pourquoi cela fonctionne si vous me dite que c'est mal.

                  Mon poste de travail est dans les combles, et cette chaleur me freine sur l'envie de passé du temps devant l’écran.

                  Merci pour vos remarques, aussi énervante soit-elle ;).

                  -
                  Edité par Crazyb0b 27 mai 2017 à 19:34:18

                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 mai 2017 à 21:27:39

                    Requête préparer: Sur le livre du site du zéro, je cite:

                    -Si vous insérez des données variable, par exemple envoyées par l'utilisateur, je vous recommande la encore de faire appel a une requête préparée...

                    Et bien ce que j'ai fait est exactement ce qui est écrie dans le livre, et ce que je disait était vrais, une requête préparée est une donnée envoyé par l'utilisateur.

                    Donc soit vous êtes une catastrophe ambulante en explication (ce qui est mon cas) soit vous avez pas compris ma demande.
                    Sujet définitivement clos!

                    -
                    Edité par Crazyb0b 28 mai 2017 à 21:30:43

                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 mai 2017 à 23:30:54

                      1. je n'ai jamais eu la prétention d'être pédagogue mais j'aurais au moins eu le mérite de te dire que c'est incorrect et d'essayer, sur mon temps, de t'expliquer en quoi
                      2. quand j'ai trouvé ton (avant-dernier) post, il avait été édité/supprimé (ne contenait plus qu'un simple "-"). A la place tu m'aurais donné le code et une description moins vague de ce "non-fonctionnement" (erreur, résultat obtenu), comme je l'avais demandé, j'aurais, comme je l'ai fait jusque-là, tenté de t'apporter mes lumières (aussi mauvaises soient-elles)
                      3. désolé pour la "pique" mais difficile d'échanger quand celui qui pose la question pense en savoir plus que les autres (pour le "Bien j'ai pas si tord que ça apparemment" donné sans plus d'explications)

                      > Une chose a la fois, il manque les closecursor aussi ;).

                      C'est facultatif, tant que le résultat (s'il y en a un) est lu, ça n'a pas d'importance.

                      > je ne comprends pas pourquoi cela fonctionne si vous me dite que c'est mal

                      "sembler fonctionner" n'est pas la preuve que c'est correct, on n'aurait pas autant de bugs en général en informatique sinon. Avec ton navigateur, essaie d'inspecter ton formulaire (clic droit dessus) et d'éditer ton champ id. Mets-y 1; DROP TABLE news; -- ou je ne sais quoi, ça supprimerait ta table, ce qui te permettra peut être de comprendre qu'une requête préparée n'est sécurisée que si elle est correctement utilisée or ce n'était pas le cas de ton code. Utiliser les méthodes prepare et execute (ie sans marqueur et en injectant directement les valeurs dans la requête) ne suffit pas et je doute que le bouquin l'enseigne ainsi.

                      D'ailleurs, comme j'en avais évoqué le cas, si tes saisies contiennent une quote ", la requête ne plante pas ? Et tu trouves ça normal ?

                      Bon courage alors, du coup ...

                      -
                      Edité par julp 29 mai 2017 à 0:49:38

                      • Partager sur Facebook
                      • Partager sur Twitter

                      [Résolu] SQLSTATE[HY093]: Invalid parameter number

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown