Principe
Introduction
Pour dialoguer entre les pages et la base de données, il faut connaître différentes informations :
Le nom de la source de données (dsn : contient le type de SGBD, l'adresse du serveur,le port de connexion, le nom de la bdd).
Un login (username).
Un mot de passe (password).
Le protocole de dialogue est toujours le même, ouverture de la connexion, création de la requête son envoi et récupération des résultats.
Méthode : Protocole
<?php
// ouverture de la connexion
host = "localhost";
$dbname = "bdd";
$port = "3306";
$dsn = "mysql:host=$host;port=$port;dbname=$dbname";
$username = 'root';
$password = 'root';
$db = new PDO($dsn, $username, $password);
// création de la requête
$sql = "SELECT * FROM auteurs";
// envoi de la requête et récupération du résultat
$liste = $db->query($sql)->fetchAll(PDO::FETCH_OBJ);
Complément : DSN
Le DSN (data source name) correspond au nom de la source de données.
Il est constitué d'un préfixe qui est le nom du SGBD utilisé.
Dans notre cas c'est :
mysql
Ensuite, on trouve l'hôte sur lequel le serveur de base de données se situe.
Dans la majorité des serveurs locaux nous devons écrire :
host=localhost
Ensuite, on trouve le port sur lequel le serveur est connecté. Vous pouvez le visualiser dans les paramètres de votre serveur de développement web. Il est aussi visible dans le haut de PhpMyAdmin.
Dans la majorité des serveurs locaux nous devons écrire :
port=3306
Et enfin, le nom de votre base de données
dbname=bdd
Ce qui nous donne :
$dsn = 'mysql:host=localhost;port=3306;dbname=bdd';
Lorsque vous choisirez un hébergeur pour votre site, celui-ci vous communiquera le nom de son serveur ainsi que le nom de votre base de données.
Complément : Login
Le login vous sera aussi fourni par votre hébergeur. En local , il vaut par défaut root.
$username = 'root';
Complément : Mot de passe
comme pour le login, le mot de passe vous sera fourni par votre hébergeur. En local, il est soit vide (wamp, laragon) soit égal à root (mamp).
$password = 'root';
Complément : PDO
La connexion aux bases de données peut se réaliser en programmation orientée objet (POO) à l'aide de la classe PDO.
$db = new PDO(...);
$db est une nouvelle instance (un objet) de la classe PDO. C'est à dire qu'elle pourra utiliser toutes les méthodes de la classe PDO.
$db->query(...)->fetchAll();
query est une méthode de PDO qui permet d'envoyer des requêtes à la BDD.
La méthode query retourne une réponse sous forme d'un objet (de la classe PDOStatement) qui possède ses propres méthodes.
fetchAll est une de ces méthodes, elle retourne le contenu complet de la requête sous forme de tableau.
$db = new PDO($dsn, $username, $password);
// création de la requête
$sql = "SELECT * FROM auteurs";
// envoi de la requête et récupération du résultat
$liste = $db->query($sql)->fetchAll();
Complément : Options
Vous pouvez ajouter des options. Par exemple, le type de codage et le retour des données sous forme d'objet :
$options = [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
];
$db = new PDO($dsn, $username, $password, $options);
Complément : query et exec
En fonction du type de requête, il existe deux méthodes pour dialoguer avec la BDD.
Si vous voulez simplement récupérer des données (SELECT), vous pouvez utiliser query.
Si vous voulez connaître le nombre de lignes affectées par votre requête (INSERT, UPDATE, DELETE), vous pouvez utiliser exec.
Exemples :
$db->query("SELECT * FROM auteurs");
$db->exec("DELETE FROM auteurs WHERE id='1'");
$db->exec("UPDATE auteurs SET nom = 'Dupond' WHERE id='1'");
$db->exec("INSERT INTO auteurs (nom, prenom) VALUES ('dupont', 'jean')");
Complément : prepare et execute
Pour des raisons de sécurité, il est préférable d'utiliser les requêtes préparées.
$statement = $db->prepare("DELETE FROM auteurs WHERE id = :id");
$statement->execute(['id' => 1]);
:id : correspond à une variable de tableau associatif appelée id.
Ce système permet d'éviter les injections sql.
Il est équivalent à :
$db->exec("DELETE FROM auteurs WHERE id='1'");
Complément : Injection sql
Supposons que vous demandiez le nom d'une personne et son mot de passe pour retourner ses articles
$nom = 'dupont'; //récupéré grace à un formulaire
$mdp = '123456'; //récupéré grace à un formulaire
$sql = "SELECT * FROM articles WHERE nom=$nom AND mdp=$mdp";
Ce qui nous donne :
$sql = "SELECT * FROM articles WHERE nom=dupont AND mdp=123456";
Monsieur Dupont verra ses articles. Maintenant supposons que le formulaire retourne ceci :
$nom = 'machin'; //récupéré grace à un formulaire
$mdp = '123456 OR 1=1'; //récupéré grace à un formulaire
$sql = "SELECT * FROM articles WHERE nom=$nom AND mdp=$mdp";
Ce qui nous donne :
$sql = "SELECT * FROM articles WHERE nom=machin AND mdp=123456 OR 1=1";
Et là, il y a un problème. Nous avons une faille de sécurité. Tous les articles de la base de données sont affichés.
Pour empêcher ces attaques, il faut nettoyer les données venant de formulaires. Notamment en ajoutant des antislashs devant les caractères spéciaux.
L'usage des requêtes préparées nous soustrait de cette obligation. En gérant les données séparément de la requête les injections sql sont annulées.