Vous êtes sur la page 1sur 33

Développement Web

coté serveur
PDO : PHP Data Object

2022

1
INTRODUCTION

2
PDO

PDO : PHP Data Objects


Extension PHP (5.1) fournissant une interface
pour accéder à une base de données depuis
PHP
Fournit une interface d'abstraction
d'abstraction pour l'accès
aux données.
Avantage : prend en charge plusieurs SGBD
avec presque le même code.

3
Bases de données supportées

Nom du pilote Bases de données prises en charge


PDO_CUBRID Cubrid
PDO_DBLIB FreeTDS / Microsoft SQL Server / Sybase
PDO_FIREBIRD Firebird
PDO_IBM IBM DB2
PDO_INFORMIX IBM Informix Dynamic Server
PDO_MYSQL MySQL 3.x/4.x/5.x
PDO_OCI Oracle Call Interface
PDO_ODBC ODBC v3 (IBM DB2, unixODBC et win32 ODBC)
PDO_PGSQL PostgreSQL
PDO_SQLITE SQLite 3 et SQLite 2
PDO_SQLSRV Microsoft SQL Server / SQL Azure

4
LES CLASSES DE PDO

5
Classes prédéfinies

PDO :
connexion PHP / base de données
__construct()
__construct()
exec(),
exec (), prepare
prepare(), (), query()
query()
errorCode(),
errorCode (), errorInfo
errorInfo() ()
getAttributes(),
getAttributes (), setAttribute()
setAttribute()
lastInsertId(),
lastInsertId (), quote()
quote()
beginTransaction()
beginTransaction ()
commit(), rollBack()
rollBack()
getAvailableDrivers()
getAvailableDrivers ()

Pour info : https://www.php.net/manual/fr/book.pdo.php 6


Classes prédéfinies

PDOStatement :
requête préparée, jeu de résultats
bindColumn(), bindParam(),
bindColumn(), bindParam(), bindValue(),
bindValue(),
closeCursor()
closeCursor ()
errorCode(),
errorCode (), errorInfo()
errorInfo()
fetch(),
fetch(), fetchAll
fetchAll(),(), fetchColumn(),
fetchColumn(), fetchObject(),
fetchObject(),
setFetchMode(),
setFetchMode (), nextRowset()
nextRowset()
rowCount(),
rowCount (), columnCount(),
columnCount(), getColumnMeta()
getColumnMeta()
getAttribute(),
getAttribute (), setAttribute()
setAttribute()
execute()
execute ()
debugDumpParams()
debugDumpParams ()

7
COMMENT SE CONNECTER ?

8
Connexions et gestionnaire de connexion

Instanciation d'un objet PDO


$dbh=new
dbh=new PDO
PDO((DSN [, user [, pass [, options ]]]);
options]]]);
DSN : Data Source Name
nom_du_driver:syntaxe_spécifique_au_driver
nom_du_driver:
Ex : mysql:host
mysql:host==localhost;dbname
localhost;dbname=
=ma_base
user : nom d'utilisateur, pass : mot de passe
options : tableau associatif
spécifiques au driver
Ex : array
array(PDO::ATTR_PERSISTENT
(PDO::ATTR_PERSISTENT => true
true)) ;
Fin de connexion : $dbh
$dbh==null ; ou unset($
unset($dbh
dbh)) ;
9
Connexions et gestionnaire de connexion

Exemple

Nom de la BD
<?php
$user= "user1";
$pass
pass== "user1pass";
$dbh = new PDO ('mysql:host
PDO(' mysql:host==localhost;dbname=
localhost;dbname=testDB',
testDB',
$user, $pass
$pass);
);
?>

10
GESTION DES ERREURS

11
Gestion des erreurs de connexion

Connexion par construction d'un objet


Gestion envisageable des erreurs
Aucune
Fin brutale (exit, die)
Exception
En cas d'erreur de connexion
Objet PDOException lancé
PDOException hérite de Exception

12
Gestion des erreurs de connexion

<?php
try {
$dbh = new PDOPDO(('mysql:host=h;dbname=db
mysql:host=h;dbname=db', ',
$user
user, , $pass
pass)) ;

$dbh = null ;
}
catch (PDOException $e) {
echo "Erreur: ".$e .$e->getMessage
getMessage() ().."<br/>
<br/>" " ;
die()
die() ;
}
?> die () est un alias de exit : c'est une fonction native
de PHP qui permet de stopper l'exécution du script. Si
une chaîne de caractères est passée en argument, elle
est affichée avant l'arrêt.
13
EFFECTUER UNE REQUÊTE

14
Exécution d'une requête

PDOStatement PDO:: query ( string request


PDO::query request))

Résultat de requête Requête

<?
<?php
php
try {
$pdo = new PDO
PDO(
("mysql:host
mysql:host=
=localhost"
localhost") ;
$pdostat = $pdo
pdo-
->query
query(
("SELECT * FROM clients"
clients") ;
}
catch (Exception $e) {
echo "ERREUR : ".$
.$e
e->getMessage
getMessage()
() ;
}

15
Exploitation des résultats d'une requête
Récupération des données d'une ligne
public PDOStatement::fetch(mode)
Récupère une ligne depuis un jeu de résultats associé à
l'objet PDOStatement. Le paramètre mode détermine la façon dont PDO
retourne la ligne.

Une ligne peut être :


un tableau indexé fetch (PDO::FETCH_NUM)
un tableau associatif fetch (PDO::FETCH_ASSOC)
un tableau mixte (par défaut) fetch (PDO::FETCH_BOTH)
un objet anonyme fetch (PDO::FETCH_OBJ)
un objet d'une classe définie par l'utilisateur
fetch(PDO::FETCH_CLASS)
Récupération des données de tous les lignes
public PDOStatement::fetchAll(mode)
16
Exploitation des résultats d'une requête (1)
Exemple 1
try {
$pdo
pdo=
=new PDO
PDO(
("mysql:host
mysql:host=
=localhost;dbname=
localhost;dbname=mysql
mysql"
") ;
$pdo
pdo-
->setAttribute
setAttribute(
(PDO
PDO::
::ATTR_ERRMODE,
ATTR_ERRMODE,
PDO::
PDO::ERRMODE_EXCEPTION
ERRMODE_EXCEPTION)
);
$pdostat = $pdo
pdo-
->query
query(
("SELECT name FROM user
user"
") ;
while ($ligne
= $pdostat
$pdostat-
->fetch
fetch(
(PDO
PDO::
::FETCH_ASSOC
FETCH_ASSOC))
)) {
echo "<p>
<p>"
" . $ligne
$ligne[
['name
name'
'] . "</p>
</p>\
\n" ;
}
}
catch (Exception $e) {
echo "ERREUR : ".$
.$e
e->getMessage
getMessage()
() ;
}
17
Exploitation des résultats d'une requête (2)
Exemple 2
try {
$pdo
pdo=
=new PDO
PDO(
("mysql:host
mysql:host=
=localhost;dbname=
localhost;dbname=mysql
mysql"
") ;
$pdo
pdo-
->setAttribute
setAttribute(
(PDO
PDO::
::ATTR_ERRMODE,
ATTR_ERRMODE,
PDO::
PDO::ERRMODE_EXCEPTION
ERRMODE_EXCEPTION)
);
$pdostat = $pdo
pdo-
->query
query(
("SELECT name FROM user"
user") ;
foreach ($pdostat
pdostat-
->fetchAll
fetchAll(
(PDO
PDO::
::FETCH_ASSOC
FETCH_ASSOC)
)
as $ligne
ligne)
) {
echo "<p>
<p>"
" . $ligne
$ligne[
['name
name'
'] . "</p>
</p>\
\n" ;
}
}
catch (Exception $e) {
echo "ERREUR : ".$
.$e
e->getMessage
getMessage()
() ;
}
18
Exploitation des résultats d'une requête (3)
Exemple
try {
$pdo
pdo=
=new PDO
PDO(
("mysql:host
mysql:host= =localhost;dbname=
localhost;dbname=mysql
mysql"") ;
$pdo
pdo-
->setAttribute
setAttribute( (PDO
PDO::
::ATTR_ERRMODE,
ATTR_ERRMODE,
PDO::
PDO::ERRMODE_EXCEPTION
ERRMODE_EXCEPTION) );
$pdostat = $pdo
pdo-
->query
query(
("SELECT name FROM user"
user") ;
$pdostat
pdostat-
->setFetchMode
setFetchMode((PDO
PDO::
::FETCH_ASSOC
FETCH_ASSOC) ) ;
foreach ($pdostat as $ligne
ligne)) {
echo "<p>
<p>"
" . $ligne
$ligne[
['name
name'
'] . "</p>
</p>\\n" ;
}
}
catch (Exception $e) {
echo "ERREUR : ".$.$e
e->getMessage
getMessage()
() ;
} setFetchMode : Définit le mode de
récupération par défaut pour cette requête 19
REQUÊTES PRÉPARÉES

20
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 :
Anonymes
Nommés
21
Préparation d'une requête

PDOStatement PDO::
PDO::prepare
prepare((string statement [,
driver_options])
array driver_options])
statement : la requête à préparer. Peut contenir des
paramètres anonymes (? (?) ou nommés (:nom
(: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
pdo=
=new PDO
PDO(
("mysql:host
mysql:host=
=localhost;dbname=
localhost;dbname=mysql
mysql"
") ;
$pdostat = $pdo
pdo-
->prepare
prepare(
(
"SELECT * FROM user WHERE User= ?"
?") ;

22
Association des paramètres d'une requête

bool PDOStatement
PDOStatement:: ::bindValue
bindValue((mixed parameter,
parameter,
mixed value [, int data_type ])
data_type])
parameter : le paramètre (nom ou position [1…n])
value : sa valeur
Associe une valeur
data_type : le type de la valeur à un paramètre
PDO::PARAM_BOOL booléen.
PDO::PARAM_NULL NULL SQL.
PDO::PARAM_INT INTEGER SQL.
PDO::PARAM_STR CHAR, VARCHAR ou autre chaîne.
PDO::PARAM_LOB "objet large" SQL.
bool PDOStatement
PDOStatement::
::execute
execute([
([array
array parameters ])
parameters])
parameters : tableau associatif ou indexé des valeurs
23
Préparation puis exécution d'une requête (1)
$pdo
pdo=
=new PDO
PDO(
("mysql:host
mysql:host==localhost;dbname=
localhost;dbname=mysql
mysql"") ;
$pdo
pdo-
->setAttribute
setAttribute(
(PDO
PDO::
::ATTR_ERRMODE,
ATTR_ERRMODE,
PDO::
PDO::ERRMODE_EXCEPTION
ERRMODE_EXCEPTION));
$pdostat = $pdo
pdo-
->prepare
prepare((
"SELECT * FROM user WHERE User= ?" ?") ;
$pdostat
pdostat-
->bindValue
bindValue(
(1, 'root
'root'
') ;
$pdostat
pdostat-
->execute
execute()
() ; paramètre anonyme
// Utilisation du résultat
$pdostat
pdostat-
->bindValue
bindValue(
(1, ‘admin
‘admin'
') ;
$pdostat
pdostat-
->execute
execute()
() ;
// Utilisation du résultat

bindValue : Associe une valeur à un nom correspondant ou


à un point d'interrogation (comme paramètre fictif) dans
la requête SQL qui a été utilisé pour préparer la
requête. 24
Préparation puis exécution d'une requête (2)
$pdo
pdo=
=new PDO
PDO(
("mysql:host
mysql:host==localhost;dbname=
localhost;dbname=mysql
mysql"
") ;
$pdo
pdo-
->setAttribute
setAttribute(
(PDO
PDO::
::ATTR_ERRMODE,
ATTR_ERRMODE,
PDO::
PDO ::ERRMODE_EXCEPTION
ERRMODE_EXCEPTION)
);
$pdostat = $pdo
pdo-
->prepare
prepare((
"SELECT * FROM user WHERE User= :utilisateur"
:utilisateur") ;
$pdostat
pdostat-
->bindValue
bindValue(
(':utilisateur
:utilisateur',
', 'root
'root'
') ;
$pdostat
pdostat-
->execute
execute()
() ;
paramètre nommé
// Utilisation du résultat
$pdostat
pdostat-
->bindValue
bindValue(
(':utilisateur
:utilisateur',
', ‘admin
admin'') ;
$pdostat
pdostat-
->execute
execute()
() ;
// Utilisation du résultat

25
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

26
ATTAQUE PAR INJECTION
SQL

27
Attaque par injection SQL ?

Ex : validation d'un login/pass


login/pass sur un site
Requête consistant à trouver un enregistrement
correspondant au couple login/pass
login/pass fourni par
l'utilisateur
SELECT *
FROM membre
WHERE login='
login='{{$_GET[
_GET[' 'login
login' ']}
]}''
AND passwd
passwd='
='{
{$_GET[
_GET[' 'passwd
passwd' ']}
]}''
Et si on essayait de fournir un mot de passe un
peu particulier…

28
Exemple concret d'injection SQL (1)
$pdo = new PDO
PDO(
('mysql:host
mysql:host=
=localhost;dbname=test
localhost;dbname=test'
') ;
$pdostat = $pdo
pdo-
->query
query(
( SELECT *
FROM membre
WHERE login='
login='{
{$_GET[
_GET['
'login
login'
']}
]}'
'
AND passwd
passwd='
='{
{$_GET[
_GET['
'passwd
passwd'
']}
]}'
' ) ;
echo "Requête:
Requête:\
\n$req
req\
\n" ;
if ($utilisateur = $pdostat
pdostat-
->fetch
fetch())
())
echo "Bienvenue {$utilisateur
utilisateur[
['nom
nom'
']}
]}"
" ;
else
echo "Désolé...
Désolé..."
" ;

29
Exemple concret d'injection SQL (2)

Saisie de l'utilisateur par formulaire :


mail : whatever
pass : who_cares
who_cares??
URL :
?mail=whatever
?mail=whatever&&passwd
passwd=
=who_cares
who_cares?
?

Requête:
SELECT *
FROM membre
WHERE login='whatever
login='whatever''
AND passwd='who_cares?
passwd='who_cares ?'
Désolé...

30
Exemple concret d'injection SQL (3)

Saisie de l'utilisateur :
mail : whatever
pass : who_cares
who_cares?'
?' OR true
true!='
!='
URL :
?mail=whatever
?mail=whatever&&passwd
passwd=
=who_cares
who_cares?'%20OR%20true!='
?'%20OR%20true!='

Requête:
SELECT *
FROM membre
WHERE login='whatever
login='whatever''
AND passwd='who_cares?'
passwd='who_cares ?' OR true!='
true!='''
Bienvenue John

31
Protection contre les injections SQL (1)
$pdo = new PDO
PDO(
('mysql:host
mysql:host==localhost;dbname=test
localhost;dbname=test'') ;
$pdostat = $pdo
pdo-
->prepare
prepare(($req = <<<
<<<SQL
SQL
SELECT *
FROM membre
WHERE login=?
AND passwd
passwd=?
=?
SQL
) ;
$pdostat
pdostat-
->execute
execute((array
array(
($_GET[
_GET[''login
login'
'],
$_GET[
_GET['
'passwd
passwd'
'])) ;
if ($utilisateur = $pdostat
pdostat-
->fetch
fetch())
())
{ echo "Bienvenue {$utilisateur
utilisateur[['nom
nom'
']}
]}\
\n" ; }
else { echo "Désole...
Désole...\\n" ; }

32
Protection contre les injections SQL (2)
$pdo = new PDO
PDO(
('mysql:host
mysql:host= =localhost;dbname=test
localhost;dbname=test' ') ;
$login = $pdo
pdo-
->quote
quote(($_GET[
_GET[' 'login
login'']) ;
$passwd = $pdo
pdo-
->quote
quote(($_GET[
_GET[' 'passwd
passwd'']) ;
$pdostat = $pdo
pdo-
->query
query(($req = <<<<<<SQL
SQL
SELECT *
FROM membre
WHERE login=
login=$$login
AND passwd
passwd==$passwd
SQL
) ;
Requête:
SELECT
echo *
"Requête:
Requête:\\n$req
req\
\n" ;
if FROM membre
($utilisateur = $pdostat
pdostat- ->fetch
fetch())
())
WHERE login='whatever
login='whatever''
{ echo
AND "Bienvenue
passwd='
passwd='who_cares {?$
who_cares? utilisateur[
utilisateur
\' OR true!=
true!=\\'[''nom
nom'
']}
]}\
\n" ; }
Désolé...
else { echo "Désole...
Désole...\ \n" ; }
33

Vous aimerez peut-être aussi