19 oct. 2008
Introduction à PDO
Par Christophe de saint leger le dimanche, octobre 19 2008, 15:18 - PHP - Lien permanent
C'est quoi PDO ?
Disponible depuis la version 5.1 de PHP PDO ( PHP DATA OBJECT ) , cette extention permet de développer des applications sans se préoccuper du SGBD qui sera utilisé ... Ainsi , si pour une raison X ou Y vous devez changer de SGBD , seuls quelques paramètres dans votre seront à modifier , vous ne devrez plus réécrire toutes vos requetes .
PDO est ecrit en C , donc plus performant que PEAR DB ou AdoBD , et donne de nombreuses possibilités au développeur , comme les requêtes préparé , transactions ect ...
Premier contact:
Nous allons voir sous forme d'exemples , différentes façons d'utiliser PDO.
Se connecter à une base de données :
//définition des variables de connexion
$user = "toto";
$pwd = "password";
//en fonction du driver
//mysql:
try{
$instancePDO = new PDO("mysql:host=127.0.0.1;dbname=mabase,$user,$pwd");
} catch (PDOException $e)
{
die("Erreur ! : ".$e->getMessage() );
}
//pgsql:
try{
$instancePDO = new PDO("pgsql:host=127.0.0.1 port=5432 dbname=mabase $user $pwd");
} catch (PDOException $e)
{
die("Erreur ! : ".$e->getMessage() );
}
//oracle
try{
$instancePDO = new PDO("oci://127.0.0.1:$port/mabase");
} catch (PDOException $e)
{
die("Erreur ! : ".$e->getMessage() );
}
Les requêtes simples:
A partir de maintenant , je considère être connecté sur une base mysql.
Ici , rien ne change , nous allons utiliser des requêtes mysql standard , la seule différence réside au niveau de la façon dont nous allons envoyer ces requêtes au serveur .
Pour ces tâches , nous allons utiliser les méthodes :
- exec()
- query()
exec():
exec sera utilisé pour les requêtes qui ne retournent pas de résultat tel que : INSERT UPDATE DELETE En revanche , exec retourne le nombre de lignes affectées par la requête.
query():
query lui est utilisé pour toutes les requêtes qui renvoient un résultat tel que : SELECT EXPLAIN SHOW DESC cette méthode renvoie une instance de la classe PDOStatement qui utilise le motif itérateur (permet de lire votre objet comme un tableau avec foreach)
Pour résumer :
INSERT => exec()
UPDATE => exec()
DELETE => exec()
SELECT => query()
EXPLAIN => query()
SHOW => query()
DESC => query()
Examples:
SELECTION:
$sql = "SELECT * FROM table LIMIT 10"; $Res = $instance->query($sql); $Tabres = $Res->fetchAll(PDO::FETCH_ASSOC); var_dump($Tabres);
l'argument de fetchAll peut être :
PDO::FETCH_ASSOC
PDO::FETCH_BOTH (par defaut)
PDO::FETCH_OBJ
Resultats:
PDO::FETCH_ASSOC
Array
(
[0] => Array
(
[champ1] => valeurA
[champ2] => valeurB
)
)
PDO::FETCH_BOTH
Array
(
[0] => Array
(
[champ1] => valeurA
[0] => valeurA
[champ2] => valeurB
[1] => valeurB
)
)
PDO::FETCH_OBJ
Array
(
[0] => stdClass Object
(
[champ1] => valeurA
[champ2] => valeurB
)
)
SUPPRESSION:
$sql = "DELETE FROM table WHERE etat=1"; $retour = $instance->exec($sql); print_r($retour);
Resultats:
//Si une erreur est srvenue FALSE //Si aucune ligne de table possede son etat = 1 0 //Si plusieurs lignes ont etat = 1 ex:10 lignes 10
Sécurité:
Pour éviter les injections SQL , il faut toujours échapper les données entrantes apres les avoir vérifiées . PDO nous donnes plusieurs façons de procéder ,
La première , est la méthode quote() qui permet d'échapper les chaînes entrantes dans votre base de données ,
Ensuite , une autre façon de faire , est d'utiliser des requêtes paramétrés , qui n'ont plus besoin d'être échappées , ce qui soulage la conscience du développeur ... et liber son esprit
.
Nous verrons plus loin comment fonctionne les requêtes paramétrées.
Les transactions:
Les transactions , permettent d'effectuer plusieurs requêtes , Mais de valider celle-ci uniquement si aucune erreurs n'a été détecté , dans le cas contraire , on annule tout ....
Les méthodes qui vont nous servir pour les transactions sont les suivantes :
beginTransaction()
commit()
rollBack()
Je pense que le mieux est d'utiliser un try catch comme ceci :
Exemple:
//La gestion d'erreur doit être en mode exception on y reviendra plus tard
$instancePDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$instancePDO->beginTransaction();
try{
$sql = "INSERT INTO ... ... ";
$instancePDO->exec($sql);
$sql = "DELETE FROM ......";
$instancePDO->exec($sql);
//si tous se passe bien
$instancePDO->commit();
} catch (Exception $e) {
//annule les requetes en cas d'erreur
$instancePDO->rollBack();
echo $e->getMessage();
}
Ainsi si une erreur se produit , sur une des requêtes , dans le bloc try , toutes actions effectuées auparavant , sera annulé , et l'on affichera le message d'erreur .
Vous avez certainement remarqué l'appel à la méthode setAttribute en haut du code , cette méthode , permet de changer le gestionnaire d'erreur de PDO . Il y a trois modes possible:
- mode silencieux , ne pas afficher les erreurs : (defaut)
PDO::ATTR_ERRMODE,PDO::ERRMODE_SILENT
- mode classique , affiche un warning:
PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING
- mode exception , lance une exception:
PDO::ATTR_ERRMODE,PDO_ERRMODE_EXCEPTION
Plusieurs méthodes sont aussi disponible pour consulter les informations sur une erreur survenue , par exemple :
errorCode()
errorInfo()
disponibles même en mode silencieux !
Les requêtes préparées:
Si vous avez une requête à exécuter de nombreuses fois dans votre script , celle-ci sera à chaque fois , analysé , précompilé optimisé puis exécuté , alors que si vous utilisez une requête préparé , ou seuls les paramètres changent , alors votre requête sera uniquement exécuté , à partir de la seconde fois , ce qui peut être un gain important en terme de performances ...
création d'une requête préparé:
Voilà à quoi ressemble une requête préparée :
$sql = 'INSERT INTO matable (champA, champB) VALUES (?, ?); ou $sql = 'INSERT INTO matable (champA, champB) VALUES (:valA, :valB); puis $inststPDO = $instancePDO->prepare($sql);
La méthode prepare() permet de donner votre requête à analyser au SGBD, et renvoie une instance de PDODtatement , tout comme la méthode query() .
Ensuite , il vous faut lier vos données à votre requête. Il existe deux façons simples de le faire . Soit directement , à l'exécution de votre requête , comme ceci :
$valA = "titi";
$valB = "toto";
(array)$param = array(
':valA'=>$valA,
':valB'=>$valB
);
$inststPDO->execute($param);
Ensuite , l'on peut aussi utiliser la méthode bindParam() qui lie une variable à un paramètre :
$valA = "titi";
$valB = "toto";
$inststPDO->bindParam(':valA',$valA);
$inststPDO->bindParam(':valB',$valB);
//enregistrement1
$inststPDO->execute();
$valA = "tata";
$valB = "tutu";
//enregistrement2 avec tata tutu
$inststPDO->execute();
Fermeture d'une ressource
En mysql , par exemple , pour libérer les ressources d'une requête , nous utilisions mysql_free_result() Et bien avec PDO , il nous suffit de spécifier notre instance PDOStatement à NULL
$inststPDO = NULL;
Voilà pour cette première approche à PDO , de nombreuse autres subtilités existent , n'hésitez pas à chercher plus loin ...
Cette article à été ecrit avec les références suivantes :
- mes connaissances
- le site de référence à PHP
- Ma bible

Commentaires
super tuto !