PDO : PHP DATA OBJECT · PDO::FETCHBOTH: retourne chaque ligne dans un tableau indexe par les noms...
Transcript of PDO : PHP DATA OBJECT · PDO::FETCHBOTH: retourne chaque ligne dans un tableau indexe par les noms...
PDO : PHP DATA OBJECT
Achref El Mouelhi
09-10 Octobre 2017, POEC PHP 2017 1 / 30
Plan
1 Introduction
2 Connexion a la BD
3 Consultation de donnees
4 Ecriture de donnees
5 POO et PDO
6 Activation des erreurs
09-10 Octobre 2017, POEC PHP 2017 2 / 30
Introduction
PHP Data Object
Plusieurs extensions possibles pour se connecter a une BDmysql
mysqli
PDO
Quel choix? !mysql et mysqli sont utilisables seulement pour se connectera une base de donnees MySQLPDO : une seule maniere pour se connecter a n’importe quellebase de donnees (Oracle, PostgreSQL, SQLITE...)
09-10 Octobre 2017, POEC PHP 2017 3 / 30
Introduction
PHP Data Object
Plusieurs extensions possibles pour se connecter a une BDmysql
mysqli
PDO
Quel choix? !mysql et mysqli sont utilisables seulement pour se connectera une base de donnees MySQLPDO : une seule maniere pour se connecter a n’importe quellebase de donnees (Oracle, PostgreSQL, SQLITE...)
09-10 Octobre 2017, POEC PHP 2017 3 / 30
Introduction
PHP Data Object
est une extension PHP pour acceder a n’importe quelle base dedonneesfournit une interface d’abstraction pour l’acces aux donneesest une interface orientee objet
09-10 Octobre 2017, POEC PHP 2017 4 / 30
Connexion a la BD
Connexion a une base de donnees
Syntaxe :
<?phpmaBase = new PDO (DSN,nom_utilisateur,motdepasse,[options]);?>
DSN : Data Source Name
mysql:host=adresse;dbname=nomBD;charset=encodage
host : localhost
dbname : location
charset : utf8
09-10 Octobre 2017, POEC PHP 2017 5 / 30
Connexion a la BD
Exemple
Exemple :
<?php$maBase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);?>
Une exception a capturerle constructeur de PDO peut lancer une exception s’il ne peut seconnecter a la base
09-10 Octobre 2017, POEC PHP 2017 6 / 30
Connexion a la BD
Gestion des exceptions
Exemple :
<?phptry{
//connexion avec la BD$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);
}catch ([PDO]Exception $e){
echo ’Erreur : ’ . $e->getMessage();die();
}?>
09-10 Octobre 2017, POEC PHP 2017 7 / 30
Connexion a la BD
Gestion des exceptions
Ou :
<?phptry{
//connexion avec la BD$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
?>
09-10 Octobre 2017, POEC PHP 2017 8 / 30
Consultation de donnees
Une requete simple : select
Pour executer une requete
se connecter a la base de donneesutiliser l’objet connexion pour effectuer les requetes
<?phptry{
//connexion avec la BD$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);//la requete$req = $mabase->query(’select * from location’);}
catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
?>
09-10 Octobre 2017, POEC PHP 2017 9 / 30
Consultation de donnees
Une requete simple : select
Pour executer une requete
se connecter a la base de donneesutiliser l’objet connexion pour effectuer les requetes
<?phptry{
//connexion avec la BD$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);//la requete$req = $mabase->query(’select * from location’);}
catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
?>
09-10 Octobre 2017, POEC PHP 2017 9 / 30
Consultation de donnees
Une requete simple : select
Afficher le resultat de la requete
Dans $req, on a le resultat de l’execution de la requete SQLAvec fetch() ou fetchAll(), on obtient le resultat sous formed’un tableau
try{
$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $mabase->query(’select * from location’);$res = $req->fetchAll();foreach ($res as $key => $value) {
echo $value[0] . " " . $value[1] . " <br/>";}
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 10 / 30
Consultation de donnees
Une requete simple : select
Afficher le resultat de la requete
Dans $req, on a le resultat de l’execution de la requete SQLAvec fetch() ou fetchAll(), on obtient le resultat sous formed’un tableau
try{
$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $mabase->query(’select * from location’);$res = $req->fetchAll();foreach ($res as $key => $value) {
echo $value[0] . " " . $value[1] . " <br/>";}
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 10 / 30
Consultation de donnees
Une requete simple : select
Ou bien
try{
$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $mabase->query(’select * from location’);while ($res = $req->fetch()){
echo implode(’;’, $res) . "<br />";}
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 11 / 30
Consultation de donnees
Fermer le curseur pour executer une autre curseur
try{
$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $mabase->query(’select * from location’);while ($res = $req->fetch()){
echo implode(’;’, $res) . "<br />";}// pour fermer le curseur$res->closeCursor();
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 12 / 30
Consultation de donnees
Pour finir la connexion
try{
$mabase = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $mabase->query(’select * from location’);while ($res = $req->fetch()){
echo implode(’;’, $res) . "<br />";}// pour finir la connexion$mabase = null;// on peut aussi utiliserunset($mabase);
}catch ([PDO]Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 13 / 30
Consultation de donnees
Mode de recuperation des donnees
Parametres de fetch()
PDO::FETCH ASSOC : retourne chaque ligne dans un tableauindexe par les noms des colonnes comme elles sont retourneesdans le jeu de resultats correspondant.PDO::FETCH NUM : retourne chaque ligne dans un tableau indexepar le numero des colonnes en commencant a 0.PDO::FETCH BOTH : retourne chaque ligne dans un tableauindexe par les noms des colonnes ainsi que leurs numeros, encommencant a 0.PDO::FETCH OBJ : retourne chaque ligne dans un objet avec lesnoms de proprietes correspondant aux noms des colonnescomme elles sont retournees dans le jeu de resultats.PDO::FETCH CLASS ou PDO::FETCH CLASSTYPE : retourneune nouvelle instance de la classe demandee, liant les colonnesaux proprietes nommees dans la classe.
09-10 Octobre 2017, POEC PHP 2017 14 / 30
Consultation de donnees
Consultation Parametree? c’est quoi?
<?php//page formulaire.php
?>
<form method=’post’ action = ’test.php’><div> nom : <input type = ’text’ name = ’nom’/></div> <br/><div> prenom : <input type = ’text’ name = ’prenom’/></div> <br /><div> <input type = ’submit’ value =’connexion’/></div></form>
09-10 Octobre 2017, POEC PHP 2017 15 / 30
Consultation de donnees
Consultation Parametree? c’est quoi?
//page test.phptry{
$pdo = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$req = $pdo->query(’select * from Personne where nom = \’’. $_POST[’nom’] .’\’and prenom = \’’ . $_POST[’prenom’].’\’’);if ( $req->fetch())
echo "Bonjour";else
echo "vous n’etes pas inscrit";$pdo=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 16 / 30
Consultation de donnees
Consultation Parametree? c’est quoi?
Injection SQL : faille XSS (cross-site scripting)
Si je saisis un nom et un prenom qui existent dans la base, jepeux me connecterMais je peux aussi me connecter en saisissant des valeurs quin’existent pas
ExempleNom : un nom qui existe vraimentPrenom : xxx ?’ or true !=’
SolutionDes fonctions speciales ou les requetes preparees
09-10 Octobre 2017, POEC PHP 2017 17 / 30
Consultation de donnees
Consultation Parametree? c’est quoi?
Injection SQL : faille XSS (cross-site scripting)
Si je saisis un nom et un prenom qui existent dans la base, jepeux me connecterMais je peux aussi me connecter en saisissant des valeurs quin’existent pas
ExempleNom : un nom qui existe vraimentPrenom : xxx ?’ or true !=’
SolutionDes fonctions speciales ou les requetes preparees
09-10 Octobre 2017, POEC PHP 2017 17 / 30
Consultation de donnees
les fonctions speciales
$nom connexion->quote($nom chaıne) : desactive lesquotes inserees par l’utilisateurhtmlspecialchars($nom chaıne) : elimine les < et >. Pourrecuperer la chaıne d’origine on peut utiliserhtmlspecialchars decode().strip tags($nom chaıne) : supprime les balises html et phpstripcslashes : supprime les antislash d’une chaıne decaractere.htmlentities($nom chaıne) : remplace les ’ ” < > par leurcode html (< ;...). Pour recuperer la chaıne d’origine on peututiliser html entity decode().addcslashes() : ajoute des slashs devant des caracteresmentionnes d’une chaıne de caractere.
09-10 Octobre 2017, POEC PHP 2017 18 / 30
Consultation de donnees
Requetes preparees? c’est quoi?En utilisant le marqueur ’?’try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$req = $bd->prepare(’select * from Personne where nom = ?and prenom = ?’);$req->execute(array($_POST[’nom’], $_POST[’prenom’]));if ( $req->fetch())
echo "Bonjour";else
echo "vous n’etes pas inscrit";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
Attention a l’ordre des parametres
09-10 Octobre 2017, POEC PHP 2017 19 / 30
Consultation de donnees
Requetes preparees? c’est quoi?En utilisant le marqueur ’?’try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$req = $bd->prepare(’select * from Personne where nom = ?and prenom = ?’);$req->execute(array($_POST[’nom’], $_POST[’prenom’]));if ( $req->fetch())
echo "Bonjour";else
echo "vous n’etes pas inscrit";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
Attention a l’ordre des parametres09-10 Octobre 2017, POEC PHP 2017 19 / 30
Consultation de donnees
Requetes preparees? c’est quoi?En utilisant le marqueur nominatif ’ :’try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$req = $bd->prepare(’select * from Personne where nom = :nom and prenom = :prenom’);$req->execute(array(’nom’ => $_POST[’nom’], ’prenom’ =>$_POST[’prenom’]));if ( $req->fetch())
echo "Bonjour";else
echo "vous n’etes pas inscrit";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 20 / 30
Consultation de donnees
Requetes preparees? c’est quoi?En utilisant le marqueur nominatif ’ :’ et bindValue()try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$req = $bd->prepare(’select * from Personne where nom = :nom and prenom = :prenom’);$req->bindValue(’:nom’,$_POST[’nom’]);$req->bindValue(’:prenom’,$_POST[’prenom’]);$req->execute();if ( $req->fetch())
echo "Bonjour";else
echo "vous n’etes pas inscrit";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 21 / 30
Ecriture de donnees
Inserer des donnees
try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’,’root’,’’);$nom = $_POST[’nom’];$prenom = $_POST[’prenom’];$bd->exec("INSERT INTO Personne (nom, prenom) VALUES(’$nom’,’$prenom’)");echo "tuple ajoute";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 22 / 30
Ecriture de donnees
Inserer des donnees avec les requetes preparees
try{
$bd = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’,’root’,’’);$nom = $_POST[’nom’];$prenom = $_POST[’prenom’];$bd->exec("INSERT INTO Personne (nom, prenom) VALUES(’$nom’,’$prenom’)");echo "tuple ajoute";$bd=null;
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 23 / 30
Ecriture de donnees
Modifier et supprimer des tuples existants
De meme pour la suppression et la modification
09-10 Octobre 2017, POEC PHP 2017 24 / 30
POO et PDO
Une classe Personne
Class Personne{private $_nom;private $_prenom;public function setNom($nom){
$this->_nom = $nom;}public function setPrenom($prenom){
$this->_prenom = $prenom;}public function Nom(){
return $this->_nom;}public function Prenom(){
return $this->_prenom;}public function decrirePersonne(){
echo "je m’appelle " . $this->Prenom() . " " . $this->Nom();
}}
09-10 Octobre 2017, POEC PHP 2017 25 / 30
POO et PDO
Utilisation de la classe pour afficher les tuples
<?phpinclude ’Personne.php’;
try{
$bd = new PDO(’mysql:host=localhost;dbname=location;charset=utf8’, ’root’, ’’);$req = $bd->query(’select * from Personne’);while($res = $req->fetch(PDO::FETCH_ASSOC)){
$perso = new Personne($res);//il faut convertir les tuples enobjets$perso->decrirePersonne();
}}
catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
?>
09-10 Octobre 2017, POEC PHP 2017 26 / 30
POO et PDO
La methode hydrate($tuple)
Class Personne{public function __construct(array $tuple){
if(count($tuple))$this->hydrate($tuple);
}public function hydrate(array $tuple){
if (isset($tuple[’nom’])){
$this->setNom($tuple[’nom’]);}if (isset($tuple[’prenom’])){
$this->setPrenom($tuple[’prenom’]);}
}}
Et quand on a plusieurs attributs (plusieurs colonnes dans la table)? !
09-10 Octobre 2017, POEC PHP 2017 27 / 30
POO et PDO
La methode hydrate($tuple)
Class Personne{public function __construct(array $tuple){
if(count($tuple))$this->hydrate($tuple);
}public function hydrate(array $tuple){
if (isset($tuple[’nom’])){
$this->setNom($tuple[’nom’]);}if (isset($tuple[’prenom’])){
$this->setPrenom($tuple[’prenom’]);}
}}
Et quand on a plusieurs attributs (plusieurs colonnes dans la table)? !
09-10 Octobre 2017, POEC PHP 2017 27 / 30
POO et PDO
Simplifier la methode hydrate($tuple)
public function hydrate(array $tuple){
//construction dynamique du setterforeach ($tuple as $key => $value){
// ucfirst() : uppercase first letter$method = ’set’.ucfirst($key);if (method_exists($this, $method)){
$this->$method($value);}
}}
09-10 Octobre 2017, POEC PHP 2017 28 / 30
Activation des erreurs
Eviter les messages d’erreurs imprecis
En instanciant un objet PDO
try{
$pdo = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));...
}catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 29 / 30
Activation des erreurs
Eviter les messages d’erreurs imprecis
ou apres l’instanciation
try{
$pdo = new PDO(’mysql:host=localhost;dbname=connexion;charset=utf8’, ’root’, ’’);$pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch (Exception $e){
die(’Erreur : ’ . $e->getMessage());}
09-10 Octobre 2017, POEC PHP 2017 30 / 30