Aidez-moi s'il vous plaît à modifier mes requêtes MySQLi en REQUÊTES PREPAREES PDO

Eléphant du PHP | 137 Messages

20 janv. 2021, 21:25

Bonsoir à tous.

S'il vous plaît j'aimerais transférer mes requêtes MySQLi qui comporte beaucoup de failles SQL. Ne comprenant pas encore très bien le concept des requêtes préparée en PDO, je sollicite votre aide pour m'aider à corriger mon code ci-après afin qu'il soit TOTALEMENT en requêtes préparées PDO:

Code : Tout sélectionner

//print_pdets.php <?php $ids = $_GET['ids'] ; $parcels = $conn->query("SELECT * FROM parcels where id in ($ids) "); $branch = array(); $branches = $conn->query("SELECT *,concat(street,', ',city,', ',state,', ',zip_code,', ',country) as address FROM branches where id in (SELECT from_branch_id FROM parcels where id in ($ids) ) or id in (SELECT to_branch_id FROM parcels where id in ($ids) ) "); while($row = $branches->fetch_assoc()): $branch[$row['id']] = $row['address']; endwhile; while($row = $parcels->fetch_assoc()): ?> //staff_list.php <?php $i = 1; $qry = $conn->query("SELECT u.*,concat(u.firstname,' ',u.lastname) as name,concat(b.street,', ',b.city,', ',b.state,', ',b.zip_code,', ',b.country) as baddress FROM users u inner join branches b on b.id = u.branch_id where u.type = 2 order by concat(u.firstname,' ',u.lastname) asc "); while($row= $qry->fetch_assoc()): ?> //user_list.php <?php $i = 1; $type = array('',"Admin","Registrar"); $qry = $conn->query("SELECT *,concat(lastname,', ',firstname,' ',middlename) as name FROM users order by concat(lastname,', ',firstname,' ',middlename) asc"); while($row= $qry->fetch_assoc()): ?> //view_parcel.php <?php $qry = $conn->query("SELECT * FROM parcels where id = ".$_GET['id'])->fetch_array(); foreach($qry as $k => $v){ $$k = $v; } $branch = array(); $branches = $conn->query("SELECT *,concat(street,', ',city,', ',state,', ',zip_code,', ',country) as address FROM branches where id in ($to_branch_id,$from_branch_id)"); while($row = $branches->fetch_assoc()): $branch[$row['id']] = $row['address']; endwhile; ?> //view_user.php <?php if(isset($_GET['id'])){ $type_arr = array('',"Admin","User"); $qry = $conn->query("SELECT *,concat(lastname,', ',firstname,' ',middlename) as name FROM users where id = ".$_GET['id'])->fetch_array(); foreach($qry as $k => $v){ $$k = $v; } } ?>
AIDEZ-MOI S'IL VOUS PLAÎT A TRANSFORMER MON CODE EN REQUÊTES PREPAREES PDO.

Merci d'avance.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

21 janv. 2021, 15:47

Salutations !

Les requêtes préparées n'ont d'intérêt que lorsque tu as besoin d'exécuter une même requête plusieurs fois en changeant uniquement ses paramètres. Autant dire que dans ton cas elles ne sont à priori pas nécessaire. Toutefois, comme elles permettent de facilement contrôler les variables utilisées pour limiter les risques (en particulier les injections SQL), elles sont presque systématiquement utilisées...

Pour préparer une requête, il suffit d'utiliser ta requête "finale" et de remplacer les variables par des identifiants du type " :identifiant " (on peut aussi utiliser l'ordre des variables avec un tableau indexé, mais c'est plus complexe à lire et à maintenir).

Lors de l'exécution de la requête préparée, on associe les variables à leurs identifiants et le moteur va les sécuriser et les intégrer dans la requête qui sera exécuté.

Par exemple :
$db = $pdo->prepare("INSERT INTO clients (nom, prenom, adresse, ville, codepostal, pays)
	VALUES (:nom, :prenom, :adresse, :ville, :cp, :pays)
");

$db->execute(array(
	':nom' => $nom,
        ':prenom' => $prenom,
        ':adresse' => $adresse,
        ':ville' => $ville,
        ':cp' => $cp,
        ':pays' => $pays
));
Il y a d'autres syntaxes possibles (avec bindParam, bindValue) et plus d'options, mais voilà le principe qui devrait te permettre de bien avancer dans ta conversion vers PDO.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 137 Messages

21 janv. 2021, 22:43

Merci beaucoup pour votre réponse. Seulement, je me demande, comment transformer cette requête-ci qui paraît un peu plus complexe en Requête PREPAREE PDO:

Code : Tout sélectionner

<?php $i = 1; $where = ""; if(isset($_GET['s'])){ $where = " where status = {$_GET['s']} "; } if($_SESSION['login_type'] != 1 ){ if(empty($where)) $where = " where "; else $where .= " and "; $where .= " (from_branch_id = {$_SESSION['login_branch_id']} or to_branch_id = {$_SESSION['login_branch_id']}) "; } $qry = $conn->query("SELECT * from parcels $where order by unix_timestamp(date_created) desc "); while($row= $qry->fetch_assoc()): ?>
Ceci est là où je calle le plus. AIDEZ-MOI S'IL VOUS PLAÎT.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

22 janv. 2021, 11:35

La requête semble un peu plus complexe dans la mesure où les critères d'exécutions peuvent changer. Ceux-ci sont affectés dynamiquement à la variable "$where" en fonction du contexte. La variable contenant les conditions à utiliser est ensuite intégrée dans la requête finale :
"SELECT * from parcels " . $where . " order by unix_timestamp(date_created) desc "
(j'ai sorti la variable de la chaine pour que ce soit plus flagrant :))

Pour la passer en PDO, le principe reste le même, il faut remplacer les éléments de ta requête qui changent par des identifiants :
" where status = {$_GET['s']} "
// deviendrait
" where status = :status "
Idem pour les valeurs issues de la session. Puis au moment de l'exécution, il suffit de passer le tableau faisant correspondre identifiant et valeur :
array ( ':status' => $_GET['s'], ... )

Pour faire quelque chose de propre (et éviter d'éventuelles erreurs si jamais une variable n'existait pas), tu pourrais également rendre la construction de ce tableau dynamique et n'ajouter de couple id/val que lorsque tu en as besoin :
$bindValues = array();
if (isset($_GET['s'])) {
  $where = " where status = :status ";
  $bindValues[':status'] = $_GET['s'];
}
Il suffira alors d'utiliser le tableau $bindValues pour l'exécution :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...