PDO une soupe et au lit !
par , 20/05/2018 � 13h33 (10039 Affichages)
- Introduction
- Exemple pratique : structure de la table SQL
- PDO Script de connexion � la base de donn�es
- Le bloc try & catch : afficher les exceptions
- Requ�te SELECT sans filtre : lister tous les enregistrements
- Requ�te SELECT avec filtre : lister les enregistrements selon crit�res
- Requ�te INSERT : ajouter un enregistrement
- Requ�te UPDATE : modifier un enregistrement
- Requ�te DELETE : supprimer un enregistrement
- Astuces et erreurs courantes
- Pour aller plus loin
- Les participants � ce billet collaboratif
1 - Introduction
PDO est une classe d�objets tout particuli�rement d�di�e � g�n�rer des variables PHP dynamiques (ici nous ne traiterons que des tableaux associatifs) en acc�dant � la base de donn�es.
PDO permet d�utiliser des requ�tes pr�par�es, et utilis�es � bon escient, les requ�tes pr�par�es permettent d��viter une attaque de votre base par un navigateur client (injection SQL). Pour les m�mes raisons, PDO g�re proprement l��chappement.
Ici, vous ne verrez QUE la technique des requ�tes pr�par�es par marqueurs anonymes. Pour utiliser la technique des requ�tes pr�par�es par marqueurs nomm�s, sauter au paragraphe 11 !
Et si vous vous dites : elle est bien gentille, Dendrite, mais j'en fais quoi moi apr�s, de son tableau PHP hein ?
Ca me dit pas comment je vais le transformer en tableau HTML !
C'est par ici, la suite logique de ce billet...
De belles boucles sans frisottis
2 - Exemple pratique : structure de la table SQL
A - un identifiant unique
L'id ou identifiant, c'est une information unique pour reconna�tre facilement un enregistrement. Dans la r�alit�, �a peut �tre votre num�ro de S�cu, votre login sur Developpez ou le num�ro de ticket que vous prenez pour faire la queue chez le boucher.
La fa�on la plus simple d'avoir un identifiant unique, c'est d'utiliser un chiffre et de faire �+1� � chaque fois qu'une ligne est cr��e. Par d�faut, un champ entier (INT) peut aller jusqu'� 2 147 483 647 (oui, plus de 2 milliards), ce qui veut dire qu'on peut cr�er une ligne toutes les secondes pendant 68 ans avant d'�tre � court de nombres.
B � auto-incr�mentation
"auto-incr�ment�", �a veut tout simplement dire qu'on va demander � la base de faire le �+1� � notre place. Pas besoin de r�fl�chir et de chercher quel est le num�ro de la derni�re ligne enregistr�e, �a se fait automatiquement.
C � La table contact
Si vous n�avez pas de base disponible, cr�ez une base nomm�e ma_base dans votre PHPMYADMIN.
Et copiez-collez ce code SQL (dans la console SQL de PHPMYADMIN) qui vous construit et vous remplit une petite table de contacts.
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 CREATE TABLE IF NOT EXISTS `contact` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nom` varchar(100) NOT NULL, `prenom` varchar(100) NOT NULL, `mail` varchar(200) NOT NULL, PRIMARY KEY (`id`), KEY `nom` (`nom`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; INSERT INTO `contact` (`id`, `nom`, `prenom`, `mail`) VALUES (1, 'ACCOYER', 'Alain', '[email protected]'), (2, 'BRABOIS', 'Bernard', '[email protected]'), (3, 'CHAZAL', 'Claire', '[email protected]'), (4, 'DENDRITE', 'Daisy', '[email protected]'), (5, 'CHAZAL', 'Etienne', '[email protected]'), (6, 'CHAZAL', 'Chantal', '[email protected]'), (7, 'CHAZAL', 'Kevin', '[email protected]'), (8, 'ZANZIBAR', 'Zoé', '[email protected]'), (9, 'CASERATI', 'Michel', '[email protected]'), (10, 'FRIPON', 'Françoise', '[email protected]');
3a - PDO - Script de connexion � la base de donnees
A la racine de votre site, dans le r�pertoire www si vous �tes sous WAMP, vous cr�ez un fichier db_mysql.php.
Et vous collez le code suivant :
Bien s�r, vous changez ce qui a besoin de l��tre dans les valeurs de votre connexion.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 <?php // @author : rawsrc - 2018 - Pour DVP // on vérifie si la fonction de connexion a déjà été définie afin d'éviter de la redéfinir if ( ! function_exists('db_connexion')) { function db_connexion() { // une fois ouverte, on renvoie toujours la même connexion static $pdo; // on vérifie si la connexion n'a pas déjà été initialisée if ( ! ($pdo instanceof PDO)) { // tentative d'ouverture de la connexion MySQL try { $pdo = new PDO('mysql:host=localhost;port=3306;dbname=ma_base;charset=utf8','root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false ]); } catch (PDOException $e) { throw new InvalidArgumentException('Erreur connexion à la base de données : '.$e->getMessage()); exit; } } // renvoi de la ressource : connexion à la base de données return $pdo; } } return db_connexion();
Comment tester votre connexion maintenant ?
En mettant juste cette ligne, sur un fichier test.php au m�me niveau que votre fichier db_mysql.php :
S'il ne g�n�re rien, c'est � dire pas d'erreur : C'est que la connexion est bonne !
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part $db = include 'db_mysql.php';
Vous pouvez supprimer le fichier test.php et passer � la suite...
3b - PDO - fermer la connexion, c'est bien.
Et c'est tout simple en plus !
L�, pour les exemples, j'ouvre et je ferme � chaque requ�te parce que je souhaite vous livrer un code directement fonctionnel.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part unset($db);
Mais comprenez-bien que sur un script, vous ouvrirez la connexion, vous ferez peut-�tre dix requ�tes, de select, d'update, d'insert, toujours avec la m�me connexion et vous ne la fermerez qu'en fin de page.
4 � Le bloc try catch : afficher les exceptions
Maintenant, vous pouvez mettre ceci sur un nouveau fichier test.php, pour comprendre � quoi sert un bloc try and catch, et la gestion des exceptions (messages d'erreurs).
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12 try{ //ici vous écrivez tout votre script //jusquà la fin, sil y a une exception, elle sera interceptée par le catch //on fait exprès d'écrire une bêtise ici //$i=0; echo $i; } catch(Exception $e){ //s'il y a un probleme PHP ou SQL, que ce soit un warning ou une erreur fatale, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
5 - Requ�te SELECT sans filtre : lister tous les enregistrements
Testez bien la requ�te dans votre PHPMYADMIN d�abord !
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3 SELECT * FROM contact ORDER BY nom, prenom;
Quand tout fonctionne, on cr�e une page "contact.php" que l'on positionne � la racine de notre site (toujours au m�me niveau que notre autre page "db_mysql.php". Elle contient ceci :
On n�a que la variable $sql � changer.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 <?php //pas de filtre $sql='SELECT * FROM contact ORDER BY nom, prenom;'; //on initialise notre tableau PHP $data=array(); $db = include 'db_mysql.php'; try{ //la ligne qui lance la requête préparée $stmt = $db->prepare($sql); //pas de filtres donc pas de paramètres $stmt->execute(); //$data est un tableau de tableaux associatifs directement exploitable ensuite dans une boucle foreach $data= $stmt->fetchAll(PDO::FETCH_ASSOC); unset($db); //$data est complet if(count($data)>0){ echo '<pre>'; print_r($data); echo '</pre>'; } //ceci n'est pas une exception //il n'y a peut-etre pas encore de donnees dans la table ! else{ echo 'Aucun resultat pour cette requete'; } } catch (Exception $e) { //s'il y a un probleme PHP ou SQL, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
6 - Requ�te SELECT avec filtre : lister les enregistrements selon crit�res
Si par ailleurs, vous souhaitez introduire des filtres � votre requ�te, votre page contact.php devra �tre construite comme suit :
On veut faire remonter tous les contacts dont le nom est � CHAZAL � et dont le pr�nom commence par � C � et dont l�id est strictement sup�rieur � 2, ce qui doit nous retourner 2 enregistrements :
Testez bien la requ�te dans votre PHPMYADMIN d�abord !
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4 SELECT id, nom, prenom, mail FROM contact WHERE nom="CHAZAL" and prenom like "C%" and id > 2 ORDER BY nom, prenom;
On positionne la page contact.php � la racine de notre site. Elle contient ceci :
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs pr�cises de filtres dans l�ordre.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 <?php //on supprime les guillemets dune chaîne SQL, PDO sen occupera $sql='SELECT id, nom, prenom, mail FROM contact WHERE nom= ? and prenom like ? and id > ? ORDER BY nom, prenom;'; //on initialise notre tableau PHP $data=array(); $db = include 'db_mysql.php'; try { //la ligne qui lance la requête préparée $stmt = $db->prepare($sql); //on affecte les marqueurs précis sur les filtres //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire $nom='CHAZAL'; $prenom_debut='C%'; $id_superieur_a=2; //Attention, bien mettre dans l'ordre de la requête ! nom puis prenom_debut puis $id_superieur_a $stmt->execute(array($nom,$prenom_debut,$id_superieur_a)); //$data est un tableau de tableaux associatifs directement exploitable ensuite dans une boucle foreach $data= $stmt->fetchAll(PDO::FETCH_ASSOC); unset($db); //$data est complet if(count($data)>0){ echo '<pre>'; print_r($data); echo '</pre>'; } //ceci n'est pas une exception //il n'y a peut etre pas de CHAZAL avec un prénom qui commence par un C et dont lid est strictement supérieur à 2 else{ echo 'Aucun resultat pour cette requete'; } } catch (Exception $e) { //s'il y a un problème PHP ou SQL, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
7 - Requ�te INSERT : ajouter un enregistrement
Si par ailleurs, vous souhaitez ins�rer des donn�es dans votre table, votre page contact.php devra �tre construite comme suit.
On veut ins�rer un nouveau contact.
Testez bien la requ�te dans votre PHPMYADMIN d�abord !
Si la requ�te SQL fonctionne, pensez-bien � supprimer Mme GAILLARD de votre table via PHPMYADMIN, avant de passer � la suite.
On positionne la page contact.php � la racine de notre site. Elle contient ceci :
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part INSERT INTO contact (id, nom, prenom, mail) VALUES (NULL, 'GAILLARD', 'Geneviève', '[email protected]');
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs pr�cises de filtres dans l�ordre.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 <?php //on supprime les guillemets dune chaîne SQL, PDO sen occupera //on remplace lid auto-increment par NULL, la table sen chargera $sql='INSERT INTO contact (id, nom, prenom, mail) VALUES (NULL, ?, ?, ?)'; $db = include 'db_mysql.php'; try { //la ligne qui lance la requête préparée $stmt = $db->prepare($sql); //on affecte les marqueurs précis sur les filtres //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire $nom='GAILLARD'; $prenom='Geneviève'; $mail='[email protected]'; //Attention, bien mettre dans l'ordre de la requête ! Nom puis prenom puis mail $stmt->execute(array($nom,$prenom,$mail)) ; // on peut récupérer le nombre de lignes affectées $nb_insert = $stmt->rowCount(); echo $nb_insert.' insertion effectuée<br/>'; unset($db); } catch (Exception $e) { //s'il y a un problème PHP ou SQL, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
8 - Requ�te UPDATE : modifier un enregistrement
Si par ailleurs, vous souhaitez modifier des donn�es existantes dans votre table, votre page contact.php devra �tre construite comme suit.
On veut corriger le mail de Mme ZANZIBAR, car on a mis .ocm au lieu de .com.
Testez bien la requ�te dans votre PHPMYADMIN d�abord !
Si la requ�te SQL fonctionne, pensez-bien ensuite � remette l�erreur �orange.ocm� via PHPMYADMIN, avant de passer � la suite.
On positionne la page contact.php � la racine de notre site. Elle contient ceci :
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part UPDATE contact SET mail = '[email protected]' WHERE contact.id = 8;
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs pr�cises de filtres dans l�ordre.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <?php //on supprime les guillemets dune chaîne SQL, PDO sen occupera $sql='UPDATE contact SET mail = ? WHERE contact.id = ?;'; $db = include 'db_mysql.php'; try { //la ligne qui lance la requête préparée $stmt = $db->prepare($sql); //on affecte les marqueurs précis sur les filtres //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire $mail='[email protected]'; $id=8; //Attention, bien mettre dans l'ordre de la requête ! mail puis id $stmt->execute(array($mail,$id)) ; // on peut récupérer le nombre de lignes affectées $nb_update = $stmt->rowCount(); echo $nb_update.' modif effectuée<br/>'; unset($db); } catch (Exception $e) { //s'il y a un problème PHP ou SQL, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
9 - Requ�te DELETE : supprimer un enregistrement
Si par ailleurs, vous souhaitez supprimer des donn�es dans votre table, votre page contact.php devra �tre construite comme suit.
On veut supprimer l�enregistrement Chantal CHAZAL, car son mail n�existe pas.
Testez bien la requ�te dans votre PHPMYADMIN d�abord !
Si la requ�te SQL fonctionne, pensez-bien � remettre Chantal CHAZAL dans votre table via PHPMYADMIN, avant de passer � la suite, et rep�rez son nouvel id !
On positionne la page contact.php � la racine de notre site. Elle contient ceci :
Code SQL : S�lectionner tout - Visualiser dans une fen�tre � part DELETE FROM contact WHERE contact.id = 6;
On doit changer la variable $sql et la ligne $stmt->execute pour placer les valeurs pr�cises de filtres dans l�ordre.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 <?php $sql='DELETE FROM contact WHERE contact.id = ?;'; $db = include 'db_mysql.php'; try { //la ligne qui lance la requête préparée $stmt = $db->prepare($sql); //on affecte le marqueur précis sur le filtre //en vrai, vous aurez plutôt des variables de type POST envoyées par un formulaire $id=6; $stmt->execute(array($id)); // on peut récupérer le nombre de lignes affectées $nb_delete = $stmt->rowCount(); echo $nb_delete.' suppression effectuée<br/>'; unset($db); } catch (Exception $e) { //s'il y a un problème PHP ou SQL, tout s'affichera ici print "Erreur ! " . $e->getMessage() . "<br/>"; }
10 - Astuces et erreurs courantes
1 - A proscrire totalement et pour toujours
Ceci est la porte ouverte aux injections SQL. PDO en soi ne pr�vient pas les injections SQL.
Code PHP : S�lectionner tout - Visualiser dans une fen�tre � part
1
2
3
4 $sql='SELECT id, nom, prenom, mail FROM contact WHERE nom="'.$_POST['nom'].'" and prenom like "'.$_POST['prenom_debut'].'" and id > '.$_POST['id_min'].' ORDER BY nom, prenom;';
https://fr.wikipedia.org/wiki/Injection_SQL
Il vous faut utiliser PDO + les requ�tes pr�par�es telles qu�expos�es ci-dessus.
2 - PDO plus obscur ?
On peut se dire la chose suivante : Ce qui �tait bien avec la requ�te ci-dessus, c�est qu�un simple echo $sql; nous permettait de copier-coller et de tester dans phpmyadmin que tout �tait bon. Et �a, ce n�est plus possible avec PDO, le rendant plus obscur.
Pourtant, il faut juste inverser la d�marche, et �a reste aussi simple. Comme montr� dans cet article, on commence par une requ�te qui fonctionne dans phpmyadmin. Dans $sql, on met des points d�interrogation � la place des valeurs en dur� et enfin, on reporte les valeurs variables PHP dans le array() des param�tres.
11 � Pour aller plus loin
Ici nous avons fait le choix de n�utiliser QUE des marqueurs anonymes (points d�interrogation).
Pour utiliser des marqueurs nomm�s, car nombre de d�veloppeurs trouvent cette m�thode plus lisible, merci de lire ce tutoriel qui va bien plus loin que ce petit article d�initiation:
PDO niveau 2 (placeholders)
https://fmaz.developpez.com/tutoriel...omprendre-pdo/
12 � Les participants � ce billet collaboratif
Ceci est un billet collaboratif : Un grand merci donc � tous les participants !
Dans l�ordre alphab�tique :
- Andry.ayme
- Celira
- Dendrite
- Jreaux62
- MaitrePylos
- ProgElect
- Rawsrc
- Willy_k
Et merci � LaurentSc pour avoir test� les codes !










