PHP PDO Jrme CUTRONA jerome cutronaunivreims fr 16

  • Slides: 50
Download presentation
PHP PDO Jérôme CUTRONA jerome. cutrona@univ-reims. fr 16: 13: 41 Programmation Web 2019 -2020

PHP PDO Jérôme CUTRONA jerome. cutrona@univ-reims. fr 16: 13: 41 Programmation Web 2019 -2020 1

INTRODUCTION 16: 13: 42 Programmation Web 2019 -2020 2

INTRODUCTION 16: 13: 42 Programmation Web 2019 -2020 2

PDO § PDO : PHP Data Objects § Extension PHP fournissant une interface pour

PDO § PDO : PHP Data Objects § Extension PHP fournissant une interface pour accéder à une base de données § Fournit une interface d'abstraction pour l'accès aux données § Ne fournit PAS une abstraction de base de données n SQL spécifique au moteur n Fonctionnalités présentes / absentes § Interface orientée objet 16: 13: 45 Programmation Web 2019 -2020 3

Bases de données supportées 16: 13: 46 Nom du pilote PDO_CUBRID Bases de données

Bases de données supportées 16: 13: 46 Nom du pilote PDO_CUBRID Bases de données prises en charge Cubrid PDO_DBLIB PDO_FIREBIRD Free. TDS / Microsoft SQL Server / Sybase Firebird PDO_IBM PDO_INFORMIX IBM DB 2 IBM Informix Dynamic Server PDO_MYSQL PDO_OCI My. SQL 3. x/4. x/5. x Oracle Call Interface PDO_ODBC PDO_PGSQL ODBC v 3 (IBM DB 2, unix. ODBC et win 32 ODBC) Postgre. SQL PDO_SQLITE PDO_SQLSRV SQLite 3 et SQLite 2 Microsoft SQL Server / SQL Azure PDO_4 D 4 D Programmation Web 2019 -2020 4

ÉCHANGES DE DONNÉES 16: 13: 48 Programmation Web 2019 -2020 5

ÉCHANGES DE DONNÉES 16: 13: 48 Programmation Web 2019 -2020 5

Échanges de données Serveur Web 1 Requête HTTP 2 Script PHP 6 Exploitation résultats

Échanges de données Serveur Web 1 Requête HTTP 2 Script PHP 6 Exploitation résultats BD 7 Réponse HTTP 8 Fin de script 3 Connexion BD 4 Requête BD 5 Résultats BD BD 9 Affichage résultat Mon PC 16: 13: 50 Serveur BD Programmation Web 2019 -2020 6 6

LES CLASSES DE PDO 16: 13: 55 Programmation Web 2019 -2020 7

LES CLASSES DE PDO 16: 13: 55 Programmation Web 2019 -2020 7

Classes prédéfinies § PDO : connexion PHP / base de données n n n

Classes prédéfinies § PDO : connexion PHP / base de données n n n n 16: 13: 57 __construct() exec(), prepare(), query() error. Code(), error. Info() get. Attributes(), set. Attribute() last. Insert. Id(), quote() begin. Transaction() commit(), roll. Back() get. Available. Drivers() Programmation Web 2019 -2020 8

Classes prédéfinies § PDOStatement : requête préparée, jeu de résultats n n n n

Classes prédéfinies § PDOStatement : requête préparée, jeu de résultats n n n n 16: 14: 01 bind. Column(), bind. Param(), bind. Value(), close. Cursor() error. Code(), error. Info() fetch(), fetch. All(), fetch. Column(), fetch. Object(), set. Fetch. Mode(), next. Rowset() row. Count(), column. Count(), get. Column. Meta() get. Attribute(), set. Attribute() execute() debug. Dump. Params() Programmation Web 2019 -2020 9

COMMENT SE CONNECTER ? 16: 14: 07 Programmation Web 2019 -2020 10

COMMENT SE CONNECTER ? 16: 14: 07 Programmation Web 2019 -2020 10

Connexions et gestionnaire de connexion § Instanciation d'un objet PDO § $dbh=new PDO(DSN [,

Connexions et gestionnaire de connexion § Instanciation d'un objet PDO § $dbh=new PDO(DSN [, user [, pass [, options]]]); § DSN : Data Source Name § nom_du_driver: syntaxe_spécifique_au_driver § Ex : 'mysql: host=localhost; dbname=ma_base' § user : nom d'utilisateur, pass : mot de passe § options : tableau associatif n n spécifiques au driver Ex : array(PDO: : ATTR_PERSISTENT => true)); § Fin de connexion : $dbh=null; /* ou */ unset($dbh); 16: 14: 13 Programmation Web 2019 -2020 11

GESTION DES ERREURS 16: 14: 15 Programmation Web 2019 -2020 12

GESTION DES ERREURS 16: 14: 15 Programmation Web 2019 -2020 12

Gestion des erreurs de connexion § Connexion par construction d'un objet § Gestion envisageable

Gestion des erreurs de connexion § Connexion par construction d'un objet § Gestion envisageable des erreurs n Aucune n Fin brutale (exit, die) n État n Exception § En cas d'erreur de connexion n Objet PDOException lancé n PDOException hérite de Exception 16: 14: 18 Programmation Web 2019 -2020 13

Gestion des erreurs de connexion <? php try { $dbh = new PDO('mysql: host=dbs;

Gestion des erreurs de connexion <? php try { $dbh = new PDO('mysql: host=dbs; dbname=music', $user, $pass) ; … $dbh = null ; } catch (PDOException $e) { echo "<p>Erreur: ". $e->get. Message() ; die() ; } 16: 14: 20 Programmation Web 2019 -2020 14

Gestion des erreurs (hormis connexion) § PDO: : ERRMODE_SILENT (par défaut) n Mode silencieux,

Gestion des erreurs (hormis connexion) § PDO: : ERRMODE_SILENT (par défaut) n Mode silencieux, mise en place d'un code d'erreur n PDO : error. Code() / error. Info() n PDOStatement : error. Code() / error. Info() § PDO: : ERRMODE_WARNING n Mise en place du code d'erreur n Émission d'une erreur de type E_WARNING § PDO: : ERRMODE_EXCEPTION n Mise en place du code d'erreur n Objet PDOException lancé 16: 14: 22 Programmation Web 2019 -2020 15

Gestion des erreurs (hormis connexion) <? php try { $dbh = new PDO('mysql: host=dbs;

Gestion des erreurs (hormis connexion) <? php try { $dbh = new PDO('mysql: host=dbs; dbname=music', $user, $pass) ; $dbh->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); … $dbh = null ; } catch (PDOException $e) { echo "<p>Erreur: ". $e->get. Message() ; die() ; } 16: 14: 23 Programmation Web 2019 -2020 16

Gestion des erreurs : code d'erreur <? php $pdo = new PDO("mysql: host=dbs; dbname=music")

Gestion des erreurs : code d'erreur <? php $pdo = new PDO("mysql: host=dbs; dbname=music") ; $pdostat = $pdo->query("COUCOU") ; if ($pdo->error. Code()) { Code SQLSTATE echo "ERREUR !!n" ; echo "<pre>n" ; var_dump($pdo->error. Info()) ; echo "</pre>n" ; Code erreur spécifique } du driver ERREUR !! array(3) { Chaîne erreur spécifique [0]=> string(5) "42000" au driver [1]=> int(1064) [2]=> string(47) "Erreur de syntaxe près de 'COUCOU' à la ligne 1" } 16: 14: 24 Programmation Web 2019 -2020 17

Gestion des erreurs : exceptions <? php try { $pdo = new PDO("mysql: host=dbs;

Gestion des erreurs : exceptions <? php try { $pdo = new PDO("mysql: host=dbs; dbname=music") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION) ; $pdostat = $pdo->query("COUCOU") ; } Code erreur spécifique catch (PDOException $e) { du driver echo "<p>ERREUR : ". $e->get. Message() ; } Chaîne erreur spécifique Code SQLSTATE au driver ERREUR : SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de 'COUCOU' à la ligne 1 16: 14: 27 Programmation Web 2019 -2020 18

EFFECTUER UNE REQUÊTE 16: 14: 29 Programmation Web 2019 -2020 19

EFFECTUER UNE REQUÊTE 16: 14: 29 Programmation Web 2019 -2020 19

Exécution d'une requête ! e § PDO: : query ( string statement ): PDOStatement

Exécution d'une requête ! e § PDO: : query ( string statement ): PDOStatement é r ts a n p e é r r a p p r e Requête Résultat de requête i s r t n n ê an tra s r b s u e o à j u u nc elq o <? php t do qu t i o ra try { d e e t s s $pdo = new PDO("mysql: host=dbs; dbname=music ") ; ê y p u q r m e e $pdostat = $pdo-> query ( " SELECT * FROM artist ") ; e r t u e q le n } é U v catch (Exception $e) s{er n". $e->get. Message() ; o echo "<p>ERREUR : c t s } e Il 16: 14: 30 Programmation Web 2019 -2020 20

Exploitation des résultats d'une requête § Récupération des données ligne à ligne § Une

Exploitation des résultats d'une requête § Récupération des données ligne à ligne § Une ligne peut être : n n n un tableau indexé un tableau associatif un tableau mixte (par défaut) un objet anonyme un objet d'une classe définie par l'utilisateur § Récupération des données d'une colonne 16: 14: 32 Programmation Web 2019 -2020 21

Parcours du résultat d'une requête § Parcourir le résultat de la requête SELECT *

Parcours du résultat d'une requête § Parcourir le résultat de la requête SELECT * FROM morceau ORDER BY mor_id Curseur interne 16: 14: 33 Résultat de requête +----------------------+ | mor_id | mor_nom | +----------------------+ | 872 | With A Little Help From My Friends | | 873 | The Letter | | 874 | Marjorine | | 875 | Midnight Rider | | 876 | You Are So Beautiful | | 877 | Feelin' Allright | | 878 | Cry Me A River |. . . Programmation Web 2019 -2020 22

Mode de récupération des résultats d'une requête $pdostat = $pdo->query( "SELECT id, name FROM

Mode de récupération des résultats d'une requête $pdostat = $pdo->query( "SELECT id, name FROM artist"); $r = $pdostat->fetch(fetch_mode)); PDO: : FETCH_NUM fetch_mode PDO: : FETCH_ASSOC PDO: : FETCH_OBJ PDO: : FETCH_CLASS, ma_classe // array $r[0] $r[1] 16: 14: 34 // ma_classe $r->id $r->name // object $r->id $r->name Programmation Web 2019 -2020 // array $r['id'] $r['name'] 23

Exploitation des résultats d'une requête (1) try { $pdo=new PDO("mysql: host=dbs; dbname=music"); $pdo->set. Attribute(PDO:

Exploitation des résultats d'une requête (1) try { $pdo=new PDO("mysql: host=dbs; dbname=music"); $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->query("SELECT id, name FROM artist"); $pdostat->set. Fetch. Mode(PDO: : FETCH_ASSOC); foreach ($pdostat as $ligne) { echo "<p>". $ligne['name']. "n"; } } catch (Exception $e) { echo "<p>ERREUR : ". $e->get. Message(); } 16: 14: 37 Programmation Web 2019 -2020 24

Exploitation des résultats d'une requête (2) try { $pdo=new PDO("mysql: host=dbs; dbname=music"); $pdo->set. Attribute(PDO:

Exploitation des résultats d'une requête (2) try { $pdo=new PDO("mysql: host=dbs; dbname=music"); $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->query("SELECT id, name FROM artist"); foreach ($pdostat->fetch. All(PDO: : FETCH_ASSOC) as $ligne) { echo "<p>". $ligne['name']. "n"; } } catch (Exception $e) { echo "<p>ERREUR : ". $e->get. Message(); } 16: 14: 38 Programmation Web 2019 -2020 25

Exploitation des résultats d'une requête (3) try { $pdo=new PDO("mysql: host=localhost; dbname=mysql") ; $pdo->set.

Exploitation des résultats d'une requête (3) try { $pdo=new PDO("mysql: host=localhost; dbname=mysql") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->query("SELECT name FROM user") ; while (($ligne = $pdostat->fetch(PDO: : FETCH_ASSOC)) !== false) { echo "<p>". $ligne['name']. "n" ; } } catch (Exception $e) { echo "<p>ERREUR : ". $e->get. Message() ; } 16: 14: 40 Programmation Web 2019 -2020 26

Modes de récupération des données (1) § PDO: : FETCH_ASSOC n retourner chaque ligne

Modes de récupération des données (1) § PDO: : FETCH_ASSOC n retourner chaque ligne dans un tableau indexé par les noms des colonnes comme elles sont retournées dans le jeu de résultats correspondant. Si le jeu de résultats contient de multiples colonnes avec le même nom, PDO: : FETCH_ASSOC retourne une seule valeur par nom de colonne. § PDO: : FETCH_NUM n 16: 14: 41 retourner chaque ligne dans un tableau indexé par le numéro des colonnes comme elles sont retournées dans le jeu de résultats correspondant, en commençant à 0. Programmation Web 2019 -2020 27

Modes de récupération des données (2) § PDO: : FETCH_BOTH (par défaut) n retourner

Modes de récupération des données (2) § PDO: : FETCH_BOTH (par défaut) n retourner chaque ligne dans un tableau indexé par les noms des colonnes ainsi que leurs numéros, comme elles sont retournées dans le jeu de résultats correspondant, en commençant à 0. § PDO: : FETCH_OBJ n 16: 14: 42 retourner chaque ligne dans un objet avec les noms de propriétés correspondant aux noms des colonnes comme elles sont retournées dans le jeu de résultats. Programmation Web 2019 -2020 28

Modes de récupération des données (3) § PDO: : FETCH_BOUND n retourner true et

Modes de récupération des données (3) § PDO: : FETCH_BOUND n retourner true et assigner les valeurs des colonnes du jeu de résultats dans les variables PHP auxquelles sont liées avec la méthode PDOStatement: : bind. Param() ou la méthode PDOStatement: : bind. Column(). § PDO: : FETCH_CLASS | PDO: : FETCH_CLASSTYPE n 16: 14: 43 retourner une nouvelle instance de la classe demandée, liant les colonnes aux propriétés nommées dans la classe. Nom de la classe = 1ère colonne. Programmation Web 2019 -2020 29

Modes de récupération des données (4) § PDO: : FETCH_INTO n met à jour

Modes de récupération des données (4) § PDO: : FETCH_INTO n met à jour une instance existante de la classe demandée, liant les colonnes du jeu de résultats aux noms des propriétés de la classe. § PDO: : FETCH_LAZY n n 16: 14: 45 retourner chaque ligne en tant qu'objet avec les noms des attributs correspondant aux noms des colonnes retournées dans le jeu de résultats. PDO: : FETCH_LAZY crée les noms des attributs de l'objet comme ils sont rencontrés. Programmation Web 2019 -2020 30

Exemple avec PDO: : FETCH_CLASS $stmt = $pdo->query(<<<SQL SELECT id, name FROM artist WHERE

Exemple avec PDO: : FETCH_CLASS $stmt = $pdo->query(<<<SQL SELECT id, name FROM artist WHERE id = 12 SQL ) ; $stmt->set. Fetch. Mode(PDO: : FETCH_CLASS, 'Artist') ; if (($object = $stmt->fetch()) !== false) { return $object ; } Instancie un objet de la classe Artist dont les attributs sont supposés être id et name, exactement le nom des champs de la table 16: 14: 46 Programmation Web 2019 -2020 31

REQUÊTES PRÉPARÉES 16: 14: 47 Programmation Web 2019 -2020 32

REQUÊTES PRÉPARÉES 16: 14: 47 Programmation Web 2019 -2020 32

Préparation d'une requête § Déroulement d'une requête SQL 1. Analyse 2. Compilation 3. Optimisation

Préparation d'une requête § Déroulement d'une requête SQL 1. Analyse 2. Compilation 3. Optimisation 4. Exécution § Exécution répétée d'une requête : 1+2+3+4 § Préparation d'une requête : 1+2+3 § Exécution répétée d'une requête préparée : 4 § Préparation en fonction de paramètres : n Anonymes n Nommés 16: 14: 48 Programmation Web 2019 -2020 33

Préparation d'une requête § PDO: : prepare(string statement [, array driver_options]): PDOStatement n n

Préparation d'une requête § PDO: : prepare(string statement [, array driver_options]): PDOStatement n n n statement : la requête à préparer. Peut contenir des paramètres anonymes (? ) ou nommés (: nom) driver_options : tableau d'options du driver retourne un objet PDOStatement qui effectuera l'association des paramètres et exécutera la requête $pdo = new PDO("mysql: host=localhost; dbname=mysql"); $pdostat = $pdo->prepare("SELECT id, name FROM artist WHERE id = ? "); 16: 14: 50 Programmation Web 2019 -2020 34

Association des paramètres d'une requête § PDOStatement: : bind. Value(mixed parameter, mixed value [,

Association des paramètres d'une requête § PDOStatement: : bind. Value(mixed parameter, mixed value [, int data_type]): bool n n n parameter : le paramètre (nom ou position [1…n]) value : sa valeur data_type : le type de la valeur § § § PDO: : PARAM_BOOL booléen. PDO: : PARAM_NULL SQL. PDO: : PARAM_INT INTEGER SQL. PDO: : PARAM_STR CHAR, VARCHAR ou autre chaîne. PDO: : PARAM_LOB "objet large" SQL. § PDOStatement: : execute([array parameters]): bool n 16: 14: 51 parameters : tableau associatif ou indexé des valeurs Programmation Web 2019 -2020 35

Préparation puis exécution d'une requête (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set.

Préparation puis exécution d'une requête (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->prepare("SELECT * FROM user WHERE login = ? ") ; $pdostat->bind. Value(1, 'root') ; paramètre anonyme $pdostat->execute() ; // Utilisation du résultat $pdostat->bind. Value(1, 'cutrona') ; $pdostat->execute() ; // Utilisation du résultat Association Préparation d'une valeur delalarequête au requête 1 er paramètre Association Exécution d'une de au 1 er paramètre 16: 14: 52 Programmation Web 2019 -2020 36

Préparation puis exécution d'une requête (2) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set.

Préparation puis exécution d'une requête (2) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->prepare("SELECT * FROM user WHERE login = : utilisateur ") ; $pdostat->bind. Value(': utilisateur', 'root') ; $pdostat->execute() ; paramètre nommé // Utilisation du résultat $pdostat->bind. Value(': utilisateur', 'cutrona') ; $pdostat->execute() ; // Utilisation du résultat Association Préparation Exécution d'une valeur de dela au larequête paramètre nommé 16: 14: 54 Programmation Web 2019 -2020 37

Préparation puis exécution d'une requête (3) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set.

Préparation puis exécution d'une requête (3) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->prepare("SELECT * FROM user WHERE login = ? ") ; $pdostat->execute(array('root')) ; paramètre anonyme // Utilisation du résultat $pdostat->execute(array('cutrona')) ; // Utilisation du résultat Association Préparation Exécution d'une valeur de delalaau requête 1 er paramètre 16: 14: 55 Programmation Web 2019 -2020 38

Préparation puis exécution d'une requête (4) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set.

Préparation puis exécution d'une requête (4) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdo->set. Attribute(PDO: : ATTR_ERRMODE, PDO: : ERRMODE_EXCEPTION); $pdostat = $pdo->prepare("SELECT * FROM user WHERE login = : utilisateur ") ; $pdostat->execute( array(': utilisateur' => 'root')) ; paramètre nommé // Utilisation du résultat $pdostat->execute( array(': utilisateur' => 'cutrona')) ; // Utilisation du résultat Association Préparation Exécution d'une valeur de dela au larequête paramètre nommé 16: 14: 56 Programmation Web 2019 -2020 39

Intérêt des requêtes préparées § Amélioration des performances en cas d'exécutions répétées § Émulation

Intérêt des requêtes préparées § Amélioration des performances en cas d'exécutions répétées § Émulation faite par PDO si le driver ne les supporte pas nativement § Protection automatique des valeurs des paramètres pour interdire les attaques par injection de code SQL 16: 14: 57 Programmation Web 2019 -2020 40

ATTAQUE PAR INJECTION SQL 16: 14: 59 Programmation Web 2019 -2020 41

ATTAQUE PAR INJECTION SQL 16: 14: 59 Programmation Web 2019 -2020 41

Attaque par injection SQL ? § Exemple : validation d'un login/password sur un site

Attaque par injection SQL ? § Exemple : validation d'un login/password sur un site § Requête consistant à trouver un enregistrement correspondant au couple login/password fourni par l'utilisateur § Requête naïve : SELECT * FROM membre WHERE login='{$_POST['login']}' AND passwd='{$_POST['passwd']}' § Et si on essayait de fournir un mot de passe un peu particulier… 16: 15: 02 Programmation Web 2019 -2020 42

Exemple concret d'injection SQL (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdostat =

Exemple concret d'injection SQL (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdostat = $pdo->query($req = <<<SQL SELECT * FROM membre WHERE login = '{$_POST['login']}' AND passwd = '{$_POST['passwd']}' SQL ) ; echo "Requête: n$reqn" ; if (($utilisateur = $pdostat->fetch())) !== false) echo "Bienvenue {$utilisateur['nom']}" ; else echo "Désolé. . . " ; 16: 15: 04 Programmation Web 2019 -2020 43

Exemple concret d'injection SQL (2) Saisie de l'utilisateur par formulaire : n login :

Exemple concret d'injection SQL (2) Saisie de l'utilisateur par formulaire : n login : whatever n pass : who_cares? Requête: SELECT * FROM membre WHERE login='whatever' AND passwd='who_cares? ' Désolé. . . 16: 15: 05 Programmation Web 2019 -2020 44

Exemple concret d'injection SQL (3) ! r u e e r t Saisie de

Exemple concret d'injection SQL (3) ! r u e e r t Saisie de l'utilisateur : b tra m e nis m n login : whatever mi e l b d a a n pass : who_cares? ' OR true!=' t ’ l a l t en e d s em e n ain g i l t r s Requête: e e l c SELECT * utes est e o t r FROM membre e mb n n e o WHERE login= 'whatever' m D r e i AND passwd=' who_cares? ' OR true!='' m e r Bienvenue John p e L 16: 15: 06 Programmation Web 2019 -2020 45

Protection contre les injections SQL (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdostat

Protection contre les injections SQL (1) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $pdostat = $pdo->prepare($req = <<<SQL SELECT * FROM membre WHERE login = ? AND passwd = ? SQL ) ; $pdostat->execute(array($_POST['login'], $_POST['passwd'])) ; if (($utilisateur = $pdostat->fetch()) !== false) { echo "Bienvenue {$utilisateur['nom']}n" ; } else { echo "Désole. . . n" ; } 16: 15: 08 Programmation Web 2019 -2020 46

Protection contre les injections SQL (2) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $login

Protection contre les injections SQL (2) $pdo = new PDO("mysql: host=dbs; dbname=app") ; $login = $pdo->quote($_POST['login']) ; $passwd = $pdo->quote($_POST['passwd']) ; $pdostat = $pdo->query($req = <<<SQL SELECT * FROM membre WHERE login = $login AND passwd = $passwd Requête: SQL SELECT * ) ; FROM membre echo "Requête: n$reqn" WHERE login= ; 'whatever' AND passwd= 'who_cares? if (($utilisateur = $pdostat ->fetch() !== false) ' OR true!='' { echo "Bienvenue {Désolé. . . $utilisateur['nom']}n" ; } else { echo "Désole. . . n" ; } 16: 15: 09 Programmation Web 2019 -2020 47

Protection contre les injections SQL : conclusion Jamais de substitution de variable dans une

Protection contre les injections SQL : conclusion Jamais de substitution de variable dans une requête SQL Jamais de concaténation dans une requête SQL Préparer une requête = augmenter son efficacité (cache) Préparer une requête = pouvoir la paramétrer Paramétrer une requête = se protéger contre l’injection de code 16: 15: 10 Programmation Web 2019 -2020 48

GESTION DES TRANSACTIONS 16: 15: 10 Programmation Web 2019 -2020 49

GESTION DES TRANSACTIONS 16: 15: 10 Programmation Web 2019 -2020 49

Transactions § Transactions : n n Atomicité, Consistance, Isolation et Durabilité BEGIN puis COMMIT

Transactions § Transactions : n n Atomicité, Consistance, Isolation et Durabilité BEGIN puis COMMIT ou ROLLBACK § Mode PDO par défaut : n § § Chaque requête est validée automatiquement PDO: : begin. Transaction() PDO: : commit() PDO: : roll. Back() Tous les moteurs ne supportent pas les transactions PDOException 16: 15: 12 Programmation Web 2019 -2020 50