11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA [email protected].

37
00:08:45 00:08:45 Programmation Web 2012-2013 Programmation Web 2012-2013 1 PHP PHP PDO PDO Jérôme CUTRONA Jérôme CUTRONA [email protected] [email protected]

Transcript of 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA [email protected].

Page 1: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

03:24:5003:24:50 Programmation Web 2012-2013Programmation Web 2012-2013 11

PHPPHPPDOPDO

Jérôme CUTRONAJérôme CUTRONA

[email protected]@univ-reims.fr

Page 2: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

2203:24:5003:24:50 Programmation Web 2012-2013Programmation Web 2012-2013

PDOPDO

PDO :PDO : P PHP HP DData ata OObjectsbjects Extension PHP fournissant une interface pour Extension PHP fournissant une interface pour

accéder à une base de donnéesaccéder à une base de données Fournit une interface d'Fournit une interface d'abstraction pour l'accès abstraction pour l'accès

aux donnéesaux données Ne fournit Ne fournit PASPAS une une abstraction de base de abstraction de base de

donnéesdonnées SQL spécifique au moteurSQL spécifique au moteur Fonctionnalités présentes / absentesFonctionnalités présentes / absentes

Interface orientée objetInterface orientée objet

Page 3: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

Bases de données supportéesBases de données supportées

Nom du driverNom du driver Bases de données supportéesBases de données supportées

PDO_DBLIBPDO_DBLIB FreeTDS / Microsoft SQL Server / SybaseFreeTDS / Microsoft SQL Server / Sybase

PDO_FIREBIRDPDO_FIREBIRD Firebird/Interbase 6Firebird/Interbase 6

PDO_IBMPDO_IBM IBM DB2IBM DB2

PDO_INFORMIXPDO_INFORMIX IBM Informix Dynamic ServerIBM Informix Dynamic Server

PDO_MYSQLPDO_MYSQL MySQL 3.x/4.x/5.xMySQL 3.x/4.x/5.x

PDO_OCIPDO_OCI Oracle Call InterfaceOracle Call Interface

PDO_ODBCPDO_ODBC ODBC v3 (IBM DB2, unixODBC et win32 ODBC)ODBC v3 (IBM DB2, unixODBC et win32 ODBC)

PDO_PGSQLPDO_PGSQL PostgreSQLPostgreSQL

PDO_SQLITEPDO_SQLITE SQLite 3 et SQLite 2SQLite 3 et SQLite 2

PDO_4DPDO_4D 4D4D

3303:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Page 4: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

4403:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Classes prédéfiniesClasses prédéfinies

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

Page 5: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

5503:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Classes prédéfiniesClasses prédéfinies

PDOStatementPDOStatement : :requête préparée, jeu de résultatsrequête préparée, jeu de résultats bindColumn(), bindParam(), bindValue(), bindColumn(), bindParam(), bindValue(),

closeCursor() closeCursor() errorCode(), errorInfo()errorCode(), errorInfo() fetch(), fetchAll(), fetchColumn(), fetchObject(), fetch(), fetchAll(), fetchColumn(), fetchObject(),

setFetchMode(), nextRowset()setFetchMode(), nextRowset() rowCount(), columnCount(), getColumnMeta()rowCount(), columnCount(), getColumnMeta() getAttribute(), setAttribute()getAttribute(), setAttribute() execute()execute() debugDumpParams()debugDumpParams()

Page 6: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

6603:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Connexions et gestionnaire de connexionConnexions et gestionnaire de connexion

Instanciation d'un objet Instanciation d'un objet PDOPDO $dbh=new $dbh=new PDOPDO((DSNDSN [, [, useruser [, [, passpass [, [, optionsoptions]]]);]]]); DSNDSN : : DData ata SSource ource NNameame

nom_du_driver:syntaxe_spécifique_au_drivernom_du_driver:syntaxe_spécifique_au_driver Ex : Ex : mysql:host=localhost;dbname=ma_basemysql:host=localhost;dbname=ma_base

useruser : nom d'utilisateur, : nom d'utilisateur, passpass : mot de passe : mot de passe optionsoptions : tableau associatif : tableau associatif

spécifiques au driverspécifiques au driver Ex : array(PDO::ATTR_PERSISTENT => true)) ;Ex : array(PDO::ATTR_PERSISTENT => true)) ;

Fin de connexion : $dbh=null ; ou unset($dbh) ;Fin de connexion : $dbh=null ; ou unset($dbh) ;

Page 7: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

7703:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs de connexion Gestion des erreurs de connexion

Connexion par construction d'un objetConnexion par construction d'un objet Gestion envisageable des erreursGestion envisageable des erreurs

AucuneAucune Fin brutale (exit, die)Fin brutale (exit, die) ÉtatÉtat ExceptionException

En cas d'erreur de connexionEn cas d'erreur de connexion Objet Objet PDOExceptionPDOException lancé lancé PDOException PDOException hérite de Exceptionhérite de Exception

Page 8: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

8803:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs de connexionGestion des erreurs de connexion

<?php<?phptrytry {{ $$dbhdbh == newnew PDOPDO((''mysql:host=h;dbname=dbmysql:host=h;dbname=db',', $$useruser, , $$passpass) ) ;; …… $$dbhdbh == null null ;;}}catchcatch ((PDOExceptionPDOException $$ee)) {{ echoecho " "Erreur: Erreur: "".$.$ee->->getMessagegetMessage()()..""<br/><br/>" " ;; diedie() () ;;}}?>?>

Page 9: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

9903:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs (hormis connexion)Gestion des erreurs (hormis connexion)

PDO::ERRMODE_SILENTPDO::ERRMODE_SILENT ( (par défautpar défaut)) Mode Mode silencieuxsilencieux, mise en place d'un , mise en place d'un code d'erreurcode d'erreur PDO : PDO : errorCodeerrorCode() / () / errorInfoerrorInfo()() PDOStatement : PDOStatement : errorCodeerrorCode() / () / errorInfoerrorInfo() ()

PDO::ERRMODE_WARNINGPDO::ERRMODE_WARNING Mise en place du Mise en place du code d'erreurcode d'erreur Émission d'une erreur de type Émission d'une erreur de type E_WARNINGE_WARNING

PDO::ERRMODE_EXCEPTIONPDO::ERRMODE_EXCEPTION Mise en place du Mise en place du code d'erreurcode d'erreur Objet Objet PDOExceptionPDOException lancé lancé

Page 10: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

101003:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs (hormis connexion)Gestion des erreurs (hormis connexion)

<?php<?phptrytry {{ $$dbhdbh == newnew PDOPDO((''mysql:host=h;dbname=dbmysql:host=h;dbname=db',', $$useruser, , $$passpass) ) ;; $$dbhdbh->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE, PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));; …… $$dbhdbh == null null ;;}}catchcatch ((PDOExceptionPDOException $$ee)) {{ echoecho " "Erreur: Erreur: "".$.$ee->->getMessagegetMessage()()..""<br/><br/>" " ;; diedie() () ;;}}?>?>

Page 11: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

111103:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs : code d'erreurGestion des erreurs : code d'erreur

<?php<?php

$$pdopdo == newnew PDOPDO((""mysql:host=localhostmysql:host=localhost"")) ;;

$$pdostatpdostat == $$pdopdo->->queryquery((""COUCOUCOUCOU"")) ;;

ifif (($$pdopdo->->errorCodeerrorCode())()) {{

echoecho " "ERREUR !!ERREUR !!\n\n" " ;;

echoecho " "<pre><pre>\n\n" " ;;

var_dumpvar_dump(($$pdopdo->->errorInfoerrorInfo())()) ;;

echoecho " "</pre></pre>\n\n" " ;;

}}

?>?> ERREUR !!ERREUR !!array(3) {array(3) { [0]=> string(5) "42000"[0]=> string(5) "42000" [1]=> int(1064)[1]=> int(1064) [2]=> string(47) "Erreur de syntaxe près de 'COUCOU' à la ligne 1"[2]=> string(47) "Erreur de syntaxe près de 'COUCOU' à la ligne 1"} }

Code SQLSTATE Code SQLSTATE

Code erreur spécifique Code erreur spécifique du driver du driver

Chaîne erreur Chaîne erreur spécifique au driverspécifique au driver

Page 12: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

121203:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Gestion des erreurs : exceptionsGestion des erreurs : exceptions

<?php<?php

trytry {{

$$pdopdo == newnew PDOPDO((""mysql:host=localhostmysql:host=localhost"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION) ) ;;

$$pdostatpdostat == $$pdopdo->->queryquery((""COUCOUCOUCOU"")) ;;

}}

catchcatch ((ExceptionException $$ee)) {{

echoecho " "ERREUR : ERREUR : "".$.$ee->->getMessagegetMessage()() ;;

}}

?>?>

ERREUR : SQLSTATE[42000]: Syntax error or access violation: 1064ERREUR : SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de 'COUCOU' à la ligne 1Erreur de syntaxe près de 'COUCOU' à la ligne 1

Code SQLSTATE Code SQLSTATE

Code erreur spécifique Code erreur spécifique du driver du driver

Chaîne erreur Chaîne erreur spécifique au driverspécifique au driver

Page 13: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

131303:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Exécution d'une requêteExécution d'une requête

PDOStatementPDOStatement PDO::queryPDO::query ( ( stringstring statementstatement ) )

<?php<?php

trytry {{

$$pdopdo == newnew PDOPDO((""mysql:host=localhostmysql:host=localhost"")) ;;

$$pdostatpdostat == $$pdopdo->->queryquery((""SELECT * FROM clientsSELECT * FROM clients"")) ;;

}}

catchcatch ((ExceptionException $$ee)) {{

echoecho " "ERREUR : ERREUR : "".$.$ee->->getMessagegetMessage()() ;;

}}

?>?>

Requête Requête Résultat de requête Résultat de requête

Page 14: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

141403:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Exploitation des résultats d'une requêteExploitation des résultats d'une requête

Récupération des données ligne à ligneRécupération des données ligne à ligne Une ligne peut être :Une ligne peut être :

un tableau indexéun tableau indexé un tableau associatifun tableau associatif un tableau mixte (par défaut)un tableau mixte (par défaut) un objet anonymeun objet anonyme un objet d'une classe définie par l'utilisateurun objet d'une classe définie par l'utilisateur

Récupération des données d'une colonneRécupération des données d'une colonne

Page 15: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

151503:24:5103:24:51 Programmation Web 2012-2013Programmation Web 2012-2013

Exploitation des résultats d'une requête (1)Exploitation des résultats d'une requête (1)

trytry {{

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->queryquery((""SELECT * FROM userSELECT * FROM user"")) ;;

$$pdostatpdostat->->setFetchModesetFetchMode((PDOPDO::::FETCH_ASSOCFETCH_ASSOC)) ;;

foreachforeach (($$pdostatpdostat asas $$ligneligne)) {{

echoecho implodeimplode(('';;', ', $$ligneligne))..""<br><br>\n\n" " ;;

}}

}}

catchcatch ((ExceptionException $$ee)) {{

echoecho " "ERREUR : ERREUR : "".$.$ee->->getMessagegetMessage()() ;;

}}

Page 16: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

161603:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Exploitation des résultats d'une requête (2)Exploitation des résultats d'une requête (2)

trytry {{

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->queryquery((""SELECT * FROM userSELECT * FROM user"")) ;;

foreachforeach (($$pdostatpdostat->->fetchAllfetchAll((PDOPDO::::FETCH_ASSOCFETCH_ASSOC))

asas $$ligneligne)) {{

echoecho implodeimplode(('';;', ', $$ligneligne))..""<br><br>\n\n" " ;;

}}

}}

catchcatch ((ExceptionException $$ee)) {{

echoecho " "ERREUR : ERREUR : "".$.$ee->->getMessagegetMessage()() ;;

}}

Page 17: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

171703:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Exploitation des résultats d'une requête (3)Exploitation des résultats d'une requête (3)

trytry {{

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->queryquery((""SELECT * FROM userSELECT * FROM user"")) ;;

whilewhile (($$ligneligne

= $= $pdostatpdostat->->fetchfetch((PDOPDO::::FETCH_ASSOCFETCH_ASSOC)))) {{

echoecho implodeimplode(('';;', ', $$ligneligne))..""<br><br>\n\n" " ;;

}}

}}

catchcatch ((ExceptionException $$ee)) {{

echoecho " "ERREUR : ERREUR : "".$.$ee->->getMessagegetMessage()() ;;

}}

Page 18: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

181803:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Modes de récupération des données (1)Modes de récupération des données (1)

PDO::FETCH_ASSOCPDO::FETCH_ASSOC retourner chaque ligne dans un retourner chaque ligne dans un tableau indexé par les tableau indexé par les

noms des colonnesnoms des colonnes comme elles sont retournées comme elles sont retournées dans le jeu de résultats correspondant. Si le jeu de dans le jeu de résultats correspondant. Si le jeu de résultats contient résultats contient de multiples colonnes avec le même de multiples colonnes avec le même nomnom, PDO::FETCH_ASSOC retourne , PDO::FETCH_ASSOC retourne une seule une seule valeur par nom de colonnevaleur par nom de colonne..

PDO::FETCH_NUMPDO::FETCH_NUM retourner retourner chaque lignechaque ligne dans un dans un tableau indexé par le tableau indexé par le

numéro des colonnesnuméro des colonnes comme elles sont retournées comme elles sont retournées dans le jeu de résultats correspondant, en dans le jeu de résultats correspondant, en commençant à 0commençant à 0..

Page 19: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

191903:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Modes de récupération des données (2)Modes de récupération des données (2)

PDO::FETCH_BOTHPDO::FETCH_BOTH retourner retourner chaque lignechaque ligne dans un dans un tableau indexé par les tableau indexé par les

noms des colonnesnoms des colonnes ainsi que leurs numérosainsi que leurs numéros, comme , comme elles sont retournées dans le jeu de résultats elles sont retournées dans le jeu de résultats correspondant, en correspondant, en commençant à 0commençant à 0..

PDO::FETCH_OBJPDO::FETCH_OBJ retourner retourner chaque lignechaque ligne dans un dans un objet avec les noms objet avec les noms

de propriétés correspondant aux noms des colonnesde propriétés correspondant aux noms des colonnes comme elles sont retournées dans le jeu de résultats.comme elles sont retournées dans le jeu de résultats.

Page 20: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

202003:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Modes de récupération des données (3)Modes de récupération des données (3)

PDO::FETCH_BOUNDPDO::FETCH_BOUND retourner retourner truetrue et et assigner les valeursassigner les valeurs des colonnes des colonnes

du jeu de résultats du jeu de résultats dans les variables PHP auxquelles dans les variables PHP auxquelles elles sont liéeselles sont liées avec la méthode avec la méthode PDOStatement::bindParam()PDOStatement::bindParam() ou la méthode ou la méthode PDOStatement::bindColumn()PDOStatement::bindColumn(). .

PDO::FETCH_CLASS | PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPEPDO::FETCH_CLASSTYPE retourner une nouvelle retourner une nouvelle instance de la classe instance de la classe

demandéedemandée, liant les colonnes aux propriétés , liant les colonnes aux propriétés nommées dans la classe.nommées dans la classe.Nom de la classe = 1ère colonneNom de la classe = 1ère colonne..

Page 21: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

212103:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Modes de récupération des données (4)Modes de récupération des données (4)

PDO::FETCH_INTOPDO::FETCH_INTO met à jour une instance existantemet à jour une instance existante de la classe de la classe

demandée, liant les demandée, liant les colonnes du jeu de résultatscolonnes du jeu de résultats aux aux noms des noms des propriétés de la classepropriétés de la classe..

PDO::FETCH_LAZYPDO::FETCH_LAZY retourner retourner chaque lignechaque ligne en tant en tant qu'objet avec les noms qu'objet avec les noms

des attributs correspondant aux noms des colonnesdes attributs correspondant aux noms des colonnes retournées dans le jeu de résultats.retournées dans le jeu de résultats.

PDO::FETCH_LAZY crée les PDO::FETCH_LAZY crée les noms des attributs de noms des attributs de l'objet comme ils sont rencontrésl'objet comme ils sont rencontrés. .

Page 22: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

222203:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation d'une requêtePréparation d'une requête

DéroulementDéroulement d'une requête SQL d'une requête SQL1.1. AnalyseAnalyse

2.2. CompilationCompilation

3.3. OptimisationOptimisation

4.4. ExécutionExécution

Exécution répétéeExécution répétée d'une requête : d'une requête : 11++22++33++44 PréparationPréparation d'une requête : d'une requête : 11++22++33 Exécution répétéeExécution répétée d'une d'une requête préparéerequête préparée : : 44 Préparation en fonction de paramètres :Préparation en fonction de paramètres :

AnonymesAnonymes NommésNommés

Page 23: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

232303:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation d'une requêtePréparation d'une requête

PDOStatementPDOStatement PDO::preparePDO::prepare((stringstring statementstatement [, [, arrayarray driver_optionsdriver_options])]) statementstatement : la requête à préparer. Peut contenir des : la requête à préparer. Peut contenir des

paramètres anonymes (paramètres anonymes (??) ou nommés () ou nommés (:nom:nom)) driver_optionsdriver_options : tableau d'options du driver : tableau d'options du driver retourne un objet retourne un objet PDOStatementPDOStatement qui effectuera qui effectuera

l'association des paramètres et exécutera la requêtel'association des paramètres et exécutera la requête

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdostatpdostat == $$pdopdo->->prepareprepare((

""SELECT * FROM user WHERE User= ?SELECT * FROM user WHERE User= ?"")) ;;

Page 24: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

242403:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

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

bool bool PDOStatement::bindValuePDOStatement::bindValue((mixed parametermixed parameter, , mixed valuemixed value [, [, int data_typeint data_type])]) parameterparameter : le paramètre (nom ou position [1…n]) : le paramètre (nom ou position [1…n]) valuevalue : sa valeur : sa valeur data_typedata_type : le type de la valeur : le type de la valeur

PDO::PARAM_BOOL PDO::PARAM_BOOL booléen. booléen. PDO::PARAM_NULL PDO::PARAM_NULL NULL SQL. NULL SQL. PDO::PARAM_INT PDO::PARAM_INT INTEGER SQL. INTEGER SQL. PDO::PARAM_STR PDO::PARAM_STR CHAR, VARCHAR ou autre chaîne. CHAR, VARCHAR ou autre chaîne. PDO::PARAM_LOB PDO::PARAM_LOB "objet large" SQL."objet large" SQL.

bool bool PDOStatement::executePDOStatement::execute([([array parametersarray parameters])]) parameters parameters : tableau associatif ou indexé des valeurs: tableau associatif ou indexé des valeurs

Page 25: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

252503:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation puis exécution d'une requête (1)Préparation puis exécution d'une requête (1)

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->prepareprepare((

""SELECT * FROM user WHERE User= ?SELECT * FROM user WHERE User= ?"")) ;;

$$pdostatpdostat->->bindValuebindValue((11, ', 'rootroot'')) ;;

$$pdostatpdostat->->executeexecute()() ;;

// Utilisation du résultat// Utilisation du résultat

$$pdostatpdostat->->bindValuebindValue((11, ', 'cutronacutrona'')) ;;

$$pdostatpdostat->->executeexecute()() ;;

// Utilisation du résultat// Utilisation du résultat

Préparation de la requêtePréparation de la requêteAssociation d'une valeur au 1Association d'une valeur au 1erer paramètre paramètreExécution de la requêteExécution de la requêteAssociation d'une valeur au 1er paramètreAssociation d'une valeur au 1er paramètreExécution de la requêteExécution de la requête

paramètre anonymeparamètre anonyme

Page 26: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

262603:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation puis exécution d'une requête (2)Préparation puis exécution d'une requête (2)

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->prepareprepare((

""SELECT * FROM user WHERE User= :utilisateurSELECT * FROM user WHERE User= :utilisateur"")) ;;

$$pdostatpdostat->->bindValuebindValue(('':utilisateur:utilisateur', '', 'rootroot'')) ;;

$$pdostatpdostat->->executeexecute()() ;;

// Utilisation du résultat// Utilisation du résultat

$$pdostatpdostat->->bindValuebindValue(('':utilisateur:utilisateur', '', 'cutronacutrona'')) ;;

$$pdostatpdostat->->executeexecute()() ;;

// Utilisation du résultat// Utilisation du résultat

Préparation de la requêtePréparation de la requêteAssociation d'une valeur au paramètre nomméAssociation d'une valeur au paramètre nomméExécution de la requêteExécution de la requêteAssociation d'une valeur au paramètre nomméAssociation d'une valeur au paramètre nomméExécution de la requêteExécution de la requête

paramètre nommé paramètre nommé

Page 27: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

272703:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation puis exécution d'une requête (3)Préparation puis exécution d'une requête (3)

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->prepareprepare((

""SELECT * FROM user WHERE User= ?SELECT * FROM user WHERE User= ?"")) ;;

$$pdostatpdostat->->executeexecute((arrayarray((''rootroot'')))) ;;

// Utilisation du résultat// Utilisation du résultat

$$pdostatpdostat->->executeexecute((arrayarray((''cutronacutrona'')) )) ;;

// Utilisation du résultat// Utilisation du résultat

Préparation de la requêtePréparation de la requêteAssociation d'une valeur au 1Association d'une valeur au 1erer paramètre paramètreExécution de la requêteExécution de la requêteAssociation d'une valeur au 1er paramètreAssociation d'une valeur au 1er paramètreExécution de la requêteExécution de la requête

paramètre anonymeparamètre anonyme

Page 28: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

282803:24:5203:24:52 Programmation Web 2012-2013Programmation Web 2012-2013

Préparation puis exécution d'une requête (4)Préparation puis exécution d'une requête (4)

$$pdopdo==newnew PDOPDO((""mysql:host=localhost;dbname=mysqlmysql:host=localhost;dbname=mysql"")) ;;

$$pdopdo->->setAttributesetAttribute((PDOPDO::::ATTR_ERRMODE,ATTR_ERRMODE,

PDOPDO::::ERRMODE_EXCEPTIONERRMODE_EXCEPTION));;

$$pdostatpdostat == $$pdopdo->->prepareprepare((

""SELECT * FROM user WHERE User= :utilisateurSELECT * FROM user WHERE User= :utilisateur"")) ;;

$$pdostatpdostat->->executeexecute((

arrayarray(('':utilisateur:utilisateur' ' => => ''rootroot'')))) ;;

// Utilisation du résultat// Utilisation du résultat

$$pdostatpdostat->->executeexecute((

arrayarray(('':utilisateur:utilisateur' ' => => ''cutronacutrona'')) )) ;;

// Utilisation du résultat// Utilisation du résultat

Préparation de la requêtePréparation de la requêteAssociation d'une valeur au paramètre nomméAssociation d'une valeur au paramètre nomméExécution de la requêteExécution de la requêteAssociation d'une valeur au paramètre nomméAssociation d'une valeur au paramètre nomméExécution de la requêteExécution de la requête

paramètre nomméparamètre nommé

Page 29: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

292903:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Intérêt des requêtes préparéesIntérêt des requêtes préparées

Amélioration des performances en cas Amélioration des performances en cas d'exécutions répétéesd'exécutions répétées

Émulation faite par PDO si le driver ne les Émulation faite par PDO si le driver ne les supporte pas nativementsupporte pas nativement

Protection automatique des valeurs des Protection automatique des valeurs des paramètres pour paramètres pour interdire les attaques par interdire les attaques par injection de code SQLinjection de code SQL

Page 30: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

303003:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Attaque par injection SQL ?Attaque par injection SQL ?

Ex : validation d'un login/pass sur un siteEx : validation d'un login/pass sur un site Requête consistant à trouver un enregistrement Requête consistant à trouver un enregistrement

correspondant au couple login/pass fourni par correspondant au couple login/pass fourni par l'utilisateurl'utilisateur

SELECTSELECT * *FROMFROM membre membreWHEREWHERE mail=' mail='{{$$_GET[_GET[''mailmail'']}]}''ANDAND passwd=' passwd='{{$$_GET[_GET[''passwdpasswd'']}]}''

Et si on essayait de fournir un mot de passe un Et si on essayait de fournir un mot de passe un peu particulier…peu particulier…

Page 31: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

313103:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Exemple concret d'injection SQL (1)Exemple concret d'injection SQL (1)

$$pdopdo == newnew PDOPDO((''mysql:host=localhost;dbname=testmysql:host=localhost;dbname=test'')) ;;

$$pdostatpdostat == $$pdopdo->->queryquery(($$reqreq == <<<<<<SQLSQL

SELECTSELECT * *

FROMFROM membre membre

WHEREWHERE mail=' mail='{{$$_GET[_GET[''mailmail'']}]}''

ANDAND passwd=' passwd='{{$$_GET[_GET[''passwdpasswd'']}]}''

SQLSQL

)) ;;

echoecho " "Requête:Requête:\n\n$$reqreq\n\n" " ;;

ifif (($$utilisateurutilisateur == $$pdostatpdostat->->fetchfetch())())

echoecho " "Bienvenue Bienvenue {{$$utilisateurutilisateur[[''nomnom'']}]}" " ;;

elseelse

echoecho " "Désolé...Désolé..." " ;;

Page 32: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

323203:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Exemple concret d'injection SQL (2)Exemple concret d'injection SQL (2)

Saisie de l'utilisateur :Saisie de l'utilisateur : mail : mail : whateverwhatever pass : pass : who_cares?who_cares?

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

Requête:Requête: SELECT *SELECT * FROM membreFROM membre WHERE mail='WHERE mail='whateverwhatever'' AND passwd='AND passwd='who_cares?who_cares?'' Désolé...Désolé...

Page 33: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

333303:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Exemple concret d'injection SQL (3)Exemple concret d'injection SQL (3)

Saisie de l'utilisateur :Saisie de l'utilisateur : mail : mail : whateverwhatever pass : pass : who_cares?' OR true!='who_cares?' OR true!='

URL :URL :?mail=whatever&passwd=who_cares?'%20OR%20true!='?mail=whatever&passwd=who_cares?'%20OR%20true!='

Requête:Requête: SELECT *SELECT * FROM membreFROM membre WHERE mail='WHERE mail='whateverwhatever'' AND passwd='AND passwd='who_cares?' OR true!='who_cares?' OR true!='''Bienvenue JohnBienvenue John

Page 34: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

343403:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Protection contre les injections SQL (1)Protection contre les injections SQL (1)

$$pdopdo == newnew PDOPDO((''mysql:host=localhost;dbname=testmysql:host=localhost;dbname=test'')) ;;

$$pdostatpdostat == $$pdopdo->->prepareprepare(($$reqreq == <<<<<<SQLSQL

SELECTSELECT * *

FROMFROM membre membre

WHEREWHERE mail=? mail=?

ANDAND passwd=? passwd=?

SQLSQL

)) ;;

$$pdostatpdostat->->executeexecute((arrayarray(($$_GET[_GET[''mailmail'']],,

$$_GET[_GET[''passwdpasswd'']))])) ;;

ifif (($$utilisateurutilisateur == $$pdostatpdostat->->fetchfetch())())

{{ echo echo " "Bienvenue Bienvenue {{$$utilisateurutilisateur[[''nomnom'']}\n]}\n" " ; ; }}

elseelse { { echoecho " "Désole...Désole...\n\n" " ; ; }}

Page 35: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

353503:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Protection contre les injections SQL (2)Protection contre les injections SQL (2)

$$pdopdo == newnew PDOPDO((''mysql:host=localhost;dbname=testmysql:host=localhost;dbname=test'')) ;;

$$mailmail == $$pdopdo->->quotequote(($$_GET[_GET[''mailmail''])]) ;;

$$passwdpasswd == $$pdopdo->->quotequote(($$_GET[_GET[''passwdpasswd''])]) ;;

$$pdostatpdostat == $$pdopdo->->queryquery(($$reqreq == <<<<<<SQLSQL

SELECTSELECT * *

FROMFROM membre membre

WHEREWHERE mail= mail=$$mailmail

ANDAND passwd= passwd=$$passwdpasswd

SQLSQL

)) ;;

echoecho " "Requête:Requête:\n\n$$reqreq\n\n" " ;;

ifif (($$utilisateurutilisateur == $$pdostatpdostat->->fetchfetch())())

{{ echo echo " "Bienvenue Bienvenue {{$$utilisateurutilisateur[[''nomnom'']}\n]}\n" " ; ; }}

elseelse { { echoecho " "Désole...Désole...\n\n" " ; ; }}

Requête:Requête: SELECT *SELECT * FROM membreFROM membre WHERE mail=WHERE mail=''whateverwhatever'' AND passwd=AND passwd=''who_cares?who_cares?\\' OR true!=' OR true!=\\''''Désolé...Désolé...

Page 36: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

363603:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

Protection contre les injections SQL (3)Protection contre les injections SQL (3)

mysql_connectmysql_connect((''localhostlocalhost'')); ; mysql_select_dbmysql_select_db((''testtest''));;

$$mailmail == mysql_real_escape_stringmysql_real_escape_string(($$_GET[_GET[''mailmail''])]);;

$$passwdpasswd == mysql_real_escape_stringmysql_real_escape_string(($$_GET[_GET[''passwdpasswd''])]);;

$$resres == mysql_querymysql_query(($$reqreq == <<<<<<SQLSQL

SELECTSELECT * * FROMFROM membre membre

WHEREWHERE mail=' mail='$$mailmail''

ANDAND passwd=' passwd='$$passwdpasswd''

SQLSQL

)) ;;

ifif ((mysql_num_rowsmysql_num_rows(($$resres) ) ==== 11 )) {{

$$utilisateurutilisateur == mysql_fetch_assocmysql_fetch_assoc(($$resres)) ;;

echoecho " "Bienvenue Bienvenue {{$$utilisateurutilisateur[[''nomnom'']}\n]}\n" " ;;

}}

elseelse {{ echoecho " "Desole...Desole...\n\n" " ;; }}

Requête:Requête: SELECT *SELECT * FROM membreFROM membre WHERE mail='WHERE mail='whateverwhatever'' AND passwd='AND passwd='who_cares?who_cares?\\' OR true!=' OR true!=\\''''Désolé...Désolé...

Page 37: 11:32:56 Programmation Web 2012-2013 1 PHP PDO Jérôme CUTRONA jerome.cutrona@univ-reims.fr.

373703:24:5303:24:53 Programmation Web 2012-2013Programmation Web 2012-2013

TransactionsTransactions

Transactions :Transactions : Atomicité, Consistance, Isolation et DurabilitéAtomicité, Consistance, Isolation et Durabilité BEGIN puis COMMIT ou ROLLBACKBEGIN puis COMMIT ou ROLLBACK

Mode PDO par défaut :Mode PDO par défaut : Chaque requête est validée automatiquementChaque requête est validée automatiquement

PDO::beginTransaction()PDO::beginTransaction() PDO::commit()PDO::commit() PDO::rollBack()PDO::rollBack() Tous les moteurs ne supportent pas les Tous les moteurs ne supportent pas les

transactions transactions PDOExceptionPDOException