Nous allons voir dans cette article l’utilisation de l’extension PDO de PHP afin de communiquer avec une base de données en effectuant des requêtes SQL.
Nous verrons également comment se protéger des attaques par injections SQL.
Tester la présence de l’extension PDO
Avant de se lancer dans ce petit article, il est toujours bon de savoir comment tester l’activation de l’extension, dans un fichier php, y inscrire :
<?php if (extension_loaded ('PDO')) { echo 'PDO chargée'; } else { echo 'PDO non chargée, activée l\'extension'; } ?>
Si besoin de l’activer, je vous invite à suivre ce lien qui vous guidera en fonction de votre système : activer PDO.
Pour cette article, j’utilise une base de test, tu peux la télécharger en cliquant sur ce lien. Pense à créer un utilisateur avec les droits dessus.
Connexion à une base de données
J’utilise une base de données MariaDB, pour une base de données MySQL, ce sera la même chose.
Pour la connexion, tu auras besoin de l’emplacement de ta base de données avec le port (souvent 3306), le nom de la base de données, l’identifiant et le mot de passe. Il est fortement conseiller d’inclure le jeu de caractère (encodage).
Pour se connecter, la ligne dans le script ressemblera à ça :
$pdo = new PDO('mysql:host=localhost;dbname=NOM_BASE;port=3306','IDENTIFIANT','MOT_DE_PASSE');
Cette ligne suffit mais pour être plus réactif en cas d’apparition d’erreur de connexion, on va tout de suite prendre l’habitude de gérer les exceptions :
$dsn = 'mysql:host=localhost;dbname=test;port:3306'; //cela rends l'ouverture de l'instance PDO plus propre à lire try { $pdo = new PDO($dsn,'IDENTIFIANT','MOT_DE_PASSE'); $pdo->exec("SET NAMES 'UTF8'"); } catch (PDOException $exception) { echo $exception->getMessage(); exit('Erreur de connexion'); }
Effectuer une requête
Nous allons voir différentes requête (INSERT, UPDATE, SELECT, DELETE) et si tu te souviens, j’ai parlé plus haut de se protéger contre les injections SQL. Je vais le faire dans cette partie.
Requête SELECT
Tout d’abord, le cas où aucune données n’est envoyé vers la base (que ce soit sur un filtre ou l’insertion de données) :
$reqSelect = $pdo->query("SELECT * FROM `testBase`); $resultat = $reqSelect->fetchAll(); // Cela récupère dans un tableau l'ensemble des résultats de la requête dans un array print_r($resultat);
Pour me protéger des injections SQL, à partir du moment où des données sont envoyées vers la base, j’ai pris cette habitude de passer mes paramètres de cette façon :
$id = 1; $nom = 'Nicolas'; $req = $pdo->prepare("SELECT * FROM `tabletest` WHERE `id` = :tagId AND `nom` = :tagNom;"); $req->bindParam('tagId', $id, PDO::PARAM_INT); $req->bindParam('tagNom', $nom, PDO::PARAM_STR); $req->execute(); $res = $req->fetch(); // récupère seulement le premier résultat. print_r($res);
Les paramètres PDO::PARAM_INT et PDO::PARAM_STR permettent de bloquer toutes les valeurs qui ne correspondent pas au type. Pour la liste des types, voir la documentation PHP.
Requête INSERT
Tu peux passer par la méthode query de l’instance PDO mais comme je l’ai dit à l’instant, à partir du moment où des données sont envoyées vers ma base, je me protège :
$nom = 'Noémie'; $req = $pdo->prepare("INSERT INTO `tabletest` (nom) VALUES (:tagNom);"); $req->bindParam('tagNom', $nom, PDO::PARAM_STR); $req->execute(); $res = $req->rowCount(); // je récupère le nombre de ligne ajoutée print_r($res); // j'affiche le nombre de ligne ajoutée
Requête UPDATE
Même principe pour un UPDATE :
$nom = 'Raphaël'; $id = 11; $req = $pdo->prepare("UPDATE `tabletest` SET `nom` = :tagNom WHERE `id` = :tagId ;"); $req->bindParam('tagNom', $nom, PDO::PARAM_STR); $req->bindParam('tagId', $id, PDO::PARAM_INT); $req->execute(); $res = $req->rowCount(); print_r($res);
Requête DELETE
On finit cet article par un DELETE :
$id = 11; $req = $pdo->prepare("DELETE FROM `tabletest` WHERE `id` = :tagId ;"); $req->bindParam('tagId', $id, PDO::PARAM_INT); $req->execute(); $res = $req->rowCount(); print_r($res);
Conclusion
Maintenant, tu es prêts à utiliser l’extension PDO pour ta connexion à la base de données tout en protégeant un minimum le trafic des données.