problème requête préparée

Eléphanteau du PHP | 10 Messages

08 avr. 2022, 12:07

Bonjour, je suis désolé de déranger pour ce genre de "bêtises" de débutant mais j'ai du mal à récupérer une donnée à partir d'une requête préparée en PDO.
J'ai un petit projet perso pour faire un CRUD de base de recettes (çà c'est pour l'explication) dans lequel j'ai 3 tables ; magazine, recettes et type_recettes.
Or j'ai une clé étrangère id_type dans la table recettes qui correspond à id_type de ma table type_recettes.
Pour résumer la situation: j'ai un formulaire HTML qui recueille les données en POST sur une nouvelle page (ajout_recettes.php).
Jusque là tout va bien. Mes valeurs sont bien récupérées.
En revanche, je n'arrive pas à exécuter une requête préparée pour récupérer l'id correspondant au type de recettes passé.
Exemple : si l'utilisateur a choisi Entrée froide (valeur que je récupère dans ma variable $_POST["nom_type'" ] dans le formulaire, je veux récupérer l'id de Entrée froide pour l'insérer dans ma table recettes.
J'ai donc créé une requête préparée (qui me semble correcte). Voici la partie du code que je n'arrive pas à faire fonctionner.
Avant tout je précise que ce n'est pas un problème de récupération de données du formulaire puisque je les ai toutes testées par des echo $_POST(cf début de mon code).
<?php
//include ('connexion.php');
try {

$bdd = new PDO('mysql:host=127.0.0.1;dbname=recettes','root','');
$bdd->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (\Exception $e) {
echo 'erreur '.$e;
}
echo "formulaire d'insertion des recettes dans la base";
echo "<br/>"
echo 'le nom de la recette est : '.$_POST["nom_recette"];
echo "<br/>";
echo 'dans le magazine '.$_POST["nom_mag"];
echo "<br/>";
echo 'Le type de recette est ' .$_POST["nom_type"];
echo "<br/>";
echo 'Elle se situe à la page N° '.$_POST["page"];
echo "<br/>";
echo 'Liste des ingrédients est ' .$_POST["ingredients"];
echo "<br/>";
echo 'La difficulté est '.$_POST["difficulte"];
echo "<br/>";
echo 'Le temps de préparation est de '.$_POST["preparation"];
echo "<br/>";
echo 'Le temps de cuisson sera de '.$_POST["cuisson"];
echo "<br/>";
//$_POST["type"];
echo $_POST["nom_type"]; //Pour tester si je récupère bien la  valeur
echo "<br/>";
$sql="SELECT id_type, nom_type from type_recettes WHERE nom_type=?";
$requete=$bdd->prepare($sql);
//var_dump($requete);
$tableau=array($_POST["nom_type"]);
$requete->execute($tableau);
//var_dump($requete);
while ($donnees=$requete->fetchObject())
{
  echo $donnees['id_type'];
  echo "<br/>";
}

?>
L'affichage du résultat de ma requête ne donne rien. Il y a donc forcément un problème dans l'exécution/paramétrage de ma requête mais je ne vois pas où.
Merci de m'éclairer.
Cordialement,
Christophe,
Supra débutant en php.

ynx
Mammouth du PHP | 586 Messages

08 avr. 2022, 13:34

Bonjour,

La requête sql et son exécution semble correcte mais pas la récupération des résultats.

Pour récupérer les résultats, tu utilises la méthode fetchObject(), la variable $donnees devrait donc être un objet, or tu l'utilises comme un tableau.
Si tu utilises fetchObject(), il faut donc accéder aux résultats dans la variables $donnees en utilisant la syntaxe objet : echo $donnees->id_type;

Si tu préfères utiliser un tableau, il faut alors remplacer la méthode fetchObject() par fetch(). Cette fonction utilisera le mode fetch par défaut défini dans la connexion à la bdd, soit PDO::FETCH_ASSOC, qui correspond bien à un tableau associatif.

Tu devrais avoir un message d'erreur PHP qui indique cette erreur. Penses à activer l'affichage des erreurs en développement ou à consulter le journal d'erreur de PHP.

Enfin, à voir comment est construit le formulaire, mais il serait peut-être mieux d'envoyer directement l'identifiant du type de la recette au lieu d'envoyer le nom du type.

Eléphanteau du PHP | 10 Messages

08 avr. 2022, 14:51


Si tu préfères utiliser un tableau, il faut alors remplacer la méthode fetchObject() par fetch(). Cette fonction utilisera le mode fetch par défaut défini dans la connexion à la bdd, soit PDO::FETCH_ASSOC, qui correspond bien à un tableau associatif.
Merci de ta réponse. En revanche cela ne prend toujours pas en compte malgré le changement de fetchObject() en fetch().
Voici le code corrigé:
$sql="SELECT id_type, nom_type from type_recettes where nom_type=?";
$requete=$bdd->prepare($sql);
//var_dump($requete);
$tableau=array($_POST["nom_type"]);
$requete->execute($tableau);
//var_dump($requete);
$donnees=$requete->fetch())

echo ($donnees['id_type']);
echo "<br/>";
Tu devrais avoir un message d'erreur PHP qui indique cette erreur. Penses à activer l'affichage des erreurs en développement ou à consulter le journal d'erreur de PHP.
J'ai activé le mode erreur puisque je l'ai fait dans mon try
$bdd->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Enfin, à voir comment est construit le formulaire, mais il serait peut-être mieux d'envoyer directement l'identifiant du type de la recette au lieu d'envoyer le nom du type.
Sauf que pour moi l'utilisateur "lambda" ne connaît pas et n'est pas sensé connaître l'id_type correspondant au type de recette. Dans mon exemple 'Entrée froide' correspond dans ma table "type_recettes" à l'id_type "1". Je devrais avoir "1" qui s'affiche dans le résultat de ma requête.
J'espère que mes explications sont claires. Si besoin je peux fournir la description de mes tables.
Je reste tout ouï si vous voyez où se situe mon problème.

Mammouth du PHP | 2703 Messages

08 avr. 2022, 15:09

J'ai activé le mode erreur puisque je l'ai fait dans mon try
$bdd->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
non, cela permet d'afficher les erreurs mysql, pas les erreurs php.

SELECT id_type, nom_type from type_recettes where nom_type=?
il faut donc saisir dans le formulaire le nom exact du type, il y a peu de chance que tous les utilisateurs fassent cela. il faut soit faire une liste déroulante des différents types et récupérer l'id du type, ou faire une recherche avec dans le where nom_type like '%nom%'

Eléphanteau du PHP | 10 Messages

08 avr. 2022, 15:59

SELECT id_type, nom_type from type_recettes where nom_type=?
il faut donc saisir dans le formulaire le nom exact du type, il y a peu de chance que tous les utilisateurs fassent cela. il faut soit faire une liste déroulante des différents types et récupérer l'id du type, ou faire une recherche avec dans le where nom_type like '%nom%'
Pardon je n'ai effectivement pas précisé que j'avais saisi le type dans une liste déroulante et c'est donc bien l'id du type que je souhaite récupérer
voici l'extrait du code du formulaire.
$sql="SELECT nom_type
      FROM type_recettes";
$resultat=mysqli_query($bdd,$sql);
// pour lister tous les types de recettes
  
//et son affichage dans le formulaire
while ($donnees=mysqli_fetch_assoc($resultat))
{
?>
<option id="type" name="type" value= "<?php echo $donnees['nom_type'];?>"><?php echo $donnees['nom_type'];?></option>
<?php
}
?>

ou alors il faudrait que dans ma requête je fasse également un SELECT de id_type que je passe en champ hidden dans mon formulaire (je comprends le principe) mais comment savoir quel type a été choisi pour renvoyer le bon id?
Merci d'avance pour vos réponses.

Mammouth du PHP | 2703 Messages

08 avr. 2022, 16:13

je ferais plutôt l'inverse, mettre l'id dans les options du select et faire une requête pour récupérer le nom du type à partir de son id si vous tenez absolument à afficher le nom du type.

$tableau=array($_POST["nom_type"]);
<option id="type" name="type"
forcément, cela marche moins bien ainsi, et l'affichage des erreurs php vous aurez mis sur la voie.

après relecture, ce n'est pas le champ name d'une option qui compte mais le champ name du select, que l'on a pas, donc pas possible de dire si c'est bien cela le problème.
Modifié en dernier par or 1 le 08 avr. 2022, 16:22, modifié 1 fois.

ynx
Mammouth du PHP | 586 Messages

08 avr. 2022, 16:19

Concernant le code corrigé, tu as des erreurs de syntaxe sur la ligne suivante (une parenthèse fermante en trop et il manque un point-virgule à la fin de la ligne) :
$donnees=$requete->fetch())

Tu as bien activé le rapport d'erreur de PDO, ce qui est une bonne chose. Mais il faut aussi activer l'affichage des erreurs de PHP en développement si c'est pas déjà le cas (en modifiant le fichier php.ini par exemple, plus d'infos ici : tutoriels/page-blanche-script-php-comme ... 73178.html)

Commence par corriger les erreurs de syntaxe et vérifier que ton code actuel avec nom_type fonctionne correctement.

Enfin concernant le fait d'utiliser id_type dans le formulaire, tu pourrais effectivement ajouter ce champ dans ta requête sql et utiliser id_type dans l'attribut value des balises options :
$sql="SELECT id_type, nom_type
      FROM type_recettes";
$resultat=mysqli_query($bdd,$sql);

while ($donnees=mysqli_fetch_assoc($resultat)) { ?>
    <option value="<?php echo $donnees['id_type']; ?>"><?php echo $donnees['nom_type']; ?></option>
<?php
}
?>
Ainsi, l'utilisateur pourra choisir l'option en fonction du nom, mais ce sera bien l'id qui sera envoyé par le formulaire.

La balise option ne devrait pas avoir d'attribut name, cet attribut est défini sur la balise select qui regroupe les balises option.