Bonsoir, suite à plusieurs sujet poster ici ( les doubles connections a une base de donnée sur la même page ) je me renseigne sur les injections sql et la securité
( passer de mysqli à pdo par ex ou bien les requêtes préparés)
Alors voilà sur mon site j'affiche les commandes des utilisateurs selon si leurs Session email corrrespond as l'email de la base de donnée j'affiche les transactions )
J'avais 2 connections une en pdo pour la connection et l'affichage du profil et une en mysqli pour l'affiche des commandes.
J'ai corriger sa pour n'avoir qu'une seule connection en pdo seulemt une chose me chiffonne
$bdd = new PDO('mysql:host=localhost;dbname=;charset=utf8', '', '');
if(isset($_SESSION['id']) AND $_SESSION['id'] > 0) {
$getid = intval($_SESSION['id']);
$requser = $bdd->prepare('SELECT * FROM membres WHERE id = ?');
$requser->execute(array($getid));
$userinfo = $requser->fetch();
RTFM. La réponse se trouve dans la documentation de la méthode que vous utilisez. => Doc de querry()
"Prépare et Exécute une requête SQL sans marque substitutive"
Note:
Si query contient des marqueurs de substitution, la requête doit être préparé et exécuté séparément en utilisant les méthodes PDO::prepare() et PDOStatement::execute().
Donc en résumé, si tu as dans la requête un paramètre variable ou que tu dois effectuer plusieurs fois la requête : tu n'utilises pas querry.
par contre le rtfm étais pas utile les 2 liens ci dessus je les ai parcouru,
Pour le rowCount dans le doc il s'utilise bien pour select
'Quant aux requêtes de type SELECT, c'est vers la méthode query qu'il faut se tourner, qui vous retourne un objet PDOStatement dont nous verrons plus tard l'exploitation. Mais vous savez d'ores et déjà que vous pouvez utiliser ce dernier pour connaître le nombre de résultats retournés via sa méthode rowCount, analogue à mysql_num_rows.' pourquoi M'en parle tu je capte pas ?
je bloque ici
payer_email= '".$_SESSION['mail']."'"
je sais qu'on peut manipuler les Get pour les injections sql , les Sessions égalements ??
$stmt = $bdd->prepare("SELECT * FROM recipes WHERE payer_email = ?");
$stmt->execute([$_SESSION['mail']]);
$data = $stmt->fetchAll();
du coup je devrais faire un code dans se genre la ?
- Edité par lutinjoyeux 10 décembre 2024 à 4:10:05
> je sais qu'on peut manipuler les Get pour les injections sql , les sessions également ??
Non mais cette donnée provient bien de l'utilisateur au départ (du $_POST quoi) ? De toute façon, le principe est de ne JAMAIS concaténer/injecter des données [directement] dans une requête SQL.
> du coup je devrais faire un code dans ce genre là ?
Oui mais ta précédente surcouche PDO aurait même permis d'écrire :
$data = $db->query('SELECT * FROM recipes WHERE payer_email = ?', [$_SESSION['mail']]);
Quant à rowCount, il est déconseillé de l'employer après une requête SELECT, officiellement elle n'était pas prévue pour remplir le rôle de mysql_num_rows (le nombre de lignes renvoyées par un SELECT notamment) mais uniquement de mysql_affected_rows (le nombre de lignes créées/modifiées par un INSERT/DELETE/UPDATE). Le pilote MySQL fait les deux (dans certaines situations ?) mais ce n'est pas valable pour tous les SGBD (PostgreSQL de mémoire) donc n'est pas portable (demain, tu changes de SGBD, ton code pourrait ne plus fonctionner à cause de ce rowCount).
TL;DR : à éviter, chose qui est en général facile à faire, il y a toujours un moyen de la remplacer, surtout pour la simple et bonne raison qu'elle est souvent très mal employée à la place d'un SELECT COUNT où vous demandez alors un résultat que vous ne parcourez ensuite jamais.
PS : perso, je ne suis pas fan du fetchAll quand je sais n'attendre qu'au plus une ligne. Un fetch, c'est plus direct, pas besoin d'un tableau intermédiaire, d'autant que tu peux tester dans le même temps si cette ligne existe ou non.
Non, lutinjoyeux, c'est la requête préparée que tu avais écrite dans ton deuxième message pour du PDO natif ou ce que j'ai écrit pour ta "surcouche"/encapsulation de PDO que tu employais dans tes précédents sujets, pas un mélange des deux comme dans ton troisième message (ce que tu as mis en deuxième argument du PDO::prepare n'a pas lieu d'être).
> if ($stmt->fetch() > 1) {
Si tu (re)prends la doc de PDOStatement::fetch, que retourne-t-elle ? Est-ce qu'une comparaison à un entier fait sens ?
Ici, pour remplacer le rowCount (dans le besoin de savoir si la requête a renvoyé au moins une ligne), l'idéal serait un do/while après un if d'une tentative de lecture du premier résultat (fetch) :
if ($row = $stmt->fetch()) { # ou, si tu préfères : if (false !== ($row = $stmt->fetch())) {
# le code HTML avec les table + thead + tr + th + tbody
do {
# le même code HTML avec les tr + td
} while ($row = $stmt->fetch());
# fermeture des tbody + table
} else {
// la table est vide/la requête n'a rien retourné
}
Cette approche n'est certainement ni facile à comprendre ni un automatisme pour les débutants. Une autre approche plus courante est fetchAll :
if ($rows = $stmt->fetchAll()) {
# le code HTML avec les table + thead + tr + th + tbody
foreach ($rows as $row) {
# le même code HTML avec les tr + td
}
# fermeture des tbody + table
} else {
// la table est vide/la requête n'a rien retourné
}
Cependant, il faut savoir que fetchAll, contrairement à fetch où tu récupères une ligne à la fois, copie tout(es les lignes) en mémoire au point potentiellement, quand il y a vraiment beaucoup de données, de dépasser la mémoire que tu peux allouer (cf memory_limit). N'utilisez pas toujours fetchAll ou assurez-vous au moins de contrôler le nombre de lignes retournées par votre requête (ie à défaut, mettez une clause LIMIT/paginez).
en faite les précedents post sur la pagination , panier et les requêtes et connexion pdo dans un fichier a part db.class.php sont dans un sous dossier par rapport au dossier membre
j'imagine que je pourrai tout regrouper et n'avoir qu'un seul fichier a part pour toutes mes requêtes préparer mais je préfère pour le moment attendre avant de tout regrouper car c'est pas ma tasse de thé de tout intégré
- Edité par lutinjoyeux 10 décembre 2024 à 15:53:35
Ici, il te faut une boucle do/while, pas while sinon tu vas "perdre" la première ligne.
> en faite les précedents post sur la pagination , panier et les requêtes et connexion pdo dans un fichier a part db.class.php sont dans un sous dossier par rapport au dossier membre
Tu organises tes fichiers comme tu veux, ça n'a pas d'incidence, c'est à ça que sert require.
> j'imagine que je pourrai tout regrouper et n'avoir qu'un seul fichier a part pour toutes mes requêtes préparer mais je préfère pour le moment attendre avant de tout regrouper car c'est pas ma tasse de thé de tout intégré
Et comment tu ferais tes binds ? En encapsulant la requête préparée dans une fonction ? Pas convaincu par l'approche, tu aurais un script énorme avec toutes les requêtes, ça te fait potentiellement deux fichiers à ouvrir au lieu d'un, pas évident de mettre les 2 en corrélations surtout pour des requêtes utilisées qu'une fois. A la rigueur, pourquoi pas pour des requêtes communes à plusieurs scripts.
J'ai donné la solution 2 posts (des miens) plus tôt, il n'y avait que 2 lignes à adapter :
while($row = $stmt->fetch()) { devenait do {
} (celle qui mettait fin à ce même while) devenait } while($row = $stmt->fetch());
Je n'ai pas parlé de fetchColumn et la requête en elle-même ne nécessitait pas de modifications (elle n'est pas censée fonctionner et avec une fonction d'agrégation sans clause group by tu n'aurais qu'une ligne de résultat).
Ni <tr>, ni <td> en-dehors de la boucle : une ligne est un enregistrement, donc un "tour de boucle" est une ligne. Il faut donc et la commencer, et la terminer dans la boucle. Comme les <td> sont des cellules dans la ligne, je pense que leur placement est ainsi logique : tout dans la ligne, donc à l'intérieur de la boucle
julp avait parlé de ne modifier que deux lignes, pas d'en déplacer d'autres
comme ceci ? arf j'ai les lignes id, nom et adresse, email, total, date qui se repète pour chaque commande au lieu d'être une seule fois en haut du tableau
Presque : toute ta partie thead + la balise ouvrante du tbody doivent se trouver entre le if et le do, pas dans le do (il te faudra donc ajouter un echo - ou, mieux, préférer la syntaxe alternative)
Presque : toute ta partie thead + la balise ouvrante du tbody doivent se trouver entre le if et le do, pas dans le do (il te faudra donc ajouter un echo - ou, mieux, préférer la syntaxe alternative)
- Edité par julp il y a 4 minutes
je venais de trouver à L'instant merci pour votre patience.
je vous souhaite une bonne soirée à vous 2
- Edité par lutinjoyeux 10 décembre 2024 à 18:49:30
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
comme ceci ? arf j'ai les lignes id, nom et adresse, email, total, date qui se repète pour chaque commande au lieu d'être une seule fois en haut du tableau
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
julp.fr ~ PHP < 8.0.0 : activer les erreurs PDO/SQL ~ PHP < 8.1.0 : activer les erreurs mysqli
la fonction _ c'est pour mon traducteur gettext