{     Accès aux bases de    données relationnelles       et ORM en PHP
{       Accès aux bases de données       relationnelles et ORM en PHP    Toute application Web dite dynamique    nécessite...
{       Accès aux bases de données       relationnelles et ORM en PHP    3 interventions :       Présentation de différent...
{   Accès aux bases de données relationnelles             Contributeur ZF depuis 2007 (Zend_Db, Zend_Barcode)             ...
{                Retournons en arrière    On a commencé par tout écrire en dur :    $lien = mysql_connect(localhost, mysql...
{                 Retournons en arrière    Puis on a ”amélioré” :        //config.php        define(DB_HOST,       localho...
{                 Retournons en arrière    Puis les classes sont arrivées :       class BDD {           var $connexion;   ...
{                        PDO    PDO = PHP Data Object    Ecrit en C    Introduit en PHP 5.0 en 2004    Activé par défaut a...
{   PDO : quelles bases de données ?    Demandez à phpinfo() :    Demandez à PDO :                 print_r(PDO::getAvailab...
{     PDO : reprenons notre exemple    La connexion :    try {        $dbh = new PDO(mysql:host=localhost;dbname= . DB_DAT...
{                    PDO : requêtes préparées       PDO peut être utilisée avec ou sans requêtes       préparées       Pou...
{           PDO : lecture des résultats    Il existe plusieurs manières de récupérer les résultats    via PDO :       $res...
{           PDO : lecture des résultats    Et plusieurs mode de récupération (PDO::FETCH_*) :       PDO::FETCH_NUM :      ...
{           PDO : lecture des résultats    Le meilleur pour la fin ? PDO::FETCH_CLASS    Prend un résultat et le retourne ...
{                     PDO::FETCH_CLASS     Notre classe :       class Utilisateur {                              private $...
{                   PDO::FETCH_CLASS    Interrogeons la base :           $stmt = $dbh->prepare(SELECT * FROM utilisateurs)...
{                Ce que PDO ne fait pas    Ne fournit pas une abstraction de base de données :        il ne réécrit pas le...
{                      Zend_Db    Composant daccès aux bases de données de Zend    Framework    Contient différents sous c...
{                    Zend_Db_Adapter    Surcharge PDO et certaines extensions    (MySQLi, Oci8, Db2, Sqlsrv) en fournissan...
{                        Zend_Db_Adapter    Exécution de requêtes préparées :          $stmt = $db->query(SELECT * FROM ut...
{    Zend_Db : lecture des résultats    Outre fetchAll() ou fetch() de PDO    (renommé en fetchRow()), on dispose de :    ...
{           Zend_Db : autres fonctions    Gestion du schéma :       listTables()       describeTable()    Interface généri...
{                       Zend_Db_Select    Abstraction DQL : permet de construire des    requêtes de type ”SELECT” en PHP  ...
{                 DoctrineDBAL    Partie de Doctrine destinée à labstraction des bases    de données :    Plusieurs sous-c...
{                           DoctrineDBAL    Connexion :     $connexion = DriverManager::getConnection(array(dbname     => ...
{          DoctrineDBAL : transation    Transaction imbriquées :     // $connexion instanceof DoctrineDBALConnection     $...
{   DoctrineDBAL : schéma manager    listDatabases()    listSequences()    listTables()    listTableColumns()    listTable...
{ DoctrineDBAL : schéma génération   Création table utilisateur :    $schema = new DoctrineDBALSchemaSchema();    $maTable...
{        Ceux quil ne faut pas oublier    ADOdb : 5.11 (PHP 5)    PEAR::MDB2 : 2.5.0 en beta (PHP 5.3+)    30/03/2011     ...
{                        ZendDb 2.0    ZendDbAdapter : ajout plugin (pre- post-connect),    suppression du SQL pur    Zend...
Prochain SlideShare
Chargement dans…5
×

Présentation de DBAL en PHP

4 857 vues

Publié le

Toute application Web dite dynamique nécessite une base de données ainsi que des outils qui permettront de manipuler ces données.

Dans la palette des outils à la disposition des développeurs PHP, on trouve entre autres les DBAL (DataBase Abstraction Layer ou couche d'abstraction de base de données) ou les ORM (Object Relational Mapping ou mapping objet-relationnel).

Publié dans : Technologie
0 commentaire
2 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
4 857
Sur SlideShare
0
Issues des intégrations
0
Intégrations
665
Actions
Partages
0
Téléchargements
44
Commentaires
0
J’aime
2
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Présentation de DBAL en PHP

  1. 1. { Accès aux bases de données relationnelles et ORM en PHP
  2. 2. { Accès aux bases de données relationnelles et ORM en PHP Toute application Web dite dynamique nécessite une base de données ainsi que des outils qui permettront de manipuler ces données. Dans la palette des outils à la disposition des développeurs PHP, on trouve entre autres les DBAL (DataBase Abstraction Layer ou couche dabstraction de base de données) ou les ORM (Object Relational Mapping ou mapping objet- relationnel). 30/03/2011 Mickaël Perraud 2
  3. 3. { Accès aux bases de données relationnelles et ORM en PHP 3 interventions : Présentation de différents DBAL Présentation de 2 ORM : Propel Doctrine2 30/03/2011 Mickaël Perraud 3
  4. 4. { Accès aux bases de données relationnelles Contributeur ZF depuis 2007 (Zend_Db, Zend_Barcode) Responsable documentation française Donne des webinars sur ZF en partenariat avec Zend Travaille sur laide à la traduction et propose les versions déconnectées de la documentation PDF / CHM Vice-trésorier AFUP 2011 @mikaelkael / http://mikaelkael.fr 30/03/2011 Mickaël Perraud 4
  5. 5. { Retournons en arrière On a commencé par tout écrire en dur : $lien = mysql_connect(localhost, mysql_user, mysql_password); if (!$lien) { die(Impossible de se connecter : . mysql_error()); } $db = mysql_select_db(foo, $lien); if (!$db) { die (Impossible de sélectionner la base de données : . mysql_error()); } $requete = SELECT * FROM maTable WHERE id = . $_GET[id]; $resultat = mysql_query($requete); while($ligne = mysql_fetch_assoc($resultat)) { echo $ligne[id].: .$ligne[valeur]; } 30/03/2011 Mickaël Perraud 5
  6. 6. { Retournons en arrière Puis on a ”amélioré” : //config.php define(DB_HOST, localhost); define(DB_USERNAME, mysql_user); define(DB_PASSWORD, mysql_password); define(DB_DATABASE, mysql_base); //db.php require_once config.php; $lien = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD); if (!$lien) { die(Impossible de se connecter : . mysql_error()); } $db = mysql_select_db(DB_DATABASE, $lien); if (!$db) { die (Impossible de sélectionner la base de données : . mysql_error()); } 30/03/2011 Mickaël Perraud 6
  7. 7. { Retournons en arrière Puis les classes sont arrivées : class BDD { var $connexion; function BDD() { $this->connexion = $this->connecte(DB_TYPE); } function connecte($type = mysql) { switch($type) { case mysql: return mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD); break; case oci8: //... 30/03/2011 Mickaël Perraud 7
  8. 8. { PDO PDO = PHP Data Object Ecrit en C Introduit en PHP 5.0 en 2004 Activé par défaut avec PHP 5.1 Fournit une interface dabstraction à laccès aux données Plus sécurisé (si bien utilisé) 30/03/2011 Mickaël Perraud 8
  9. 9. { PDO : quelles bases de données ? Demandez à phpinfo() : Demandez à PDO : print_r(PDO::getAvailableDrivers()); /* Array ( [0] => sqlite [1] => dblib [2] => mysql [3] => oci [4] => odbc [5] => pgsql [6] => sqlite2 ) */ 30/03/2011 Mickaël Perraud 9
  10. 10. { PDO : reprenons notre exemple La connexion : try { $dbh = new PDO(mysql:host=localhost;dbname= . DB_DATABASE, DB_USER, DB_PASSWORD); echo Connected!; } catch (PDOException $e) { echo $e->getMessage(); } En changeant de driver : try { $dbh = new PDO(oci:dbname= . DB_DATABASE, DB_USER, DB_PASSWORD); echo Connected!; } catch (PDOException $e) { echo $e->getMessage(); } Ce qui va suivre est désormais indépendant du driver 30/03/2011 Mickaël Perraud 10
  11. 11. { PDO : requêtes préparées PDO peut être utilisée avec ou sans requêtes préparées Pour des raisons de sécurité, préférez les requêtes préparées : $stmt = $dbh->prepare(SELECT nom, prenom FROM utilisateurs WHERE id_utilisateur = :id); $stmt->bindParam(id, $_GET[id], PDO::PARAM_INT); $stmt->execute(); $resultat = $stmt->fetchAll(); Lassignation peut être nommée (ci-dessus) ou numérique 30/03/2011 Mickaël Perraud 11
  12. 12. { PDO : lecture des résultats Il existe plusieurs manières de récupérer les résultats via PDO : $resultat = $stmt->fetchAll(PDO::FETCH_...); // Toutes les lignes //ou $resultat = $stmt->fetch(PDO::FETCH_...); // Ligne par ligne Et plusieurs mode de récupération (PDO::FETCH_*) : PDO::FETCH_ASSOC : Array ( [nom] => Perraud [prenom] => Mickael ) 30/03/2011 Mickaël Perraud 12
  13. 13. { PDO : lecture des résultats Et plusieurs mode de récupération (PDO::FETCH_*) : PDO::FETCH_NUM : Array ( [0] => Perraud [1] => Mickael ) PDO::FETCH_BOTH (par défaut) : Array ( [nom] => Perraud [0] => Perraud [prenom] => Mickael [1] => Mickael ) PDO::FETCH_OBJ : object(stdClass)#1 (2) { ["nom"]=> string(7) "Perraud" ["prenom"]=> string(7) "Mickael" } 30/03/2011 Mickaël Perraud 13
  14. 14. { PDO : lecture des résultats Le meilleur pour la fin ? PDO::FETCH_CLASS Prend un résultat et le retourne sous la forme dune classe On peut instancier la classe directement par PDO 30/03/2011 Mickaël Perraud 14
  15. 15. { PDO::FETCH_CLASS Notre classe : class Utilisateur { private $_nom; private $_prenom; public function __set($attribut, $valeur) { $this->{"set".ucfirst($attribut)} = $valeur; } public function setNom($nom) { $this->_nom = $nom; } public function getNom() class Utilisateur { { public $nom; return $this->_nom; public $prenom; } } public function setPrenom($prenom) { $this->_prenom = $prenom; } public function getPrenom() { return $this->_prenom; } public function __toString() { return $this->_prenom . . $this->_nom; } } 30/03/2011 Mickaël Perraud 15
  16. 16. { PDO::FETCH_CLASS Interrogeons la base : $stmt = $dbh->prepare(SELECT * FROM utilisateurs); $resultat = $stmt->fetchAll(PDO::FETCH_CLASS, Utilisateur); foreach($resultat as $class) { echo $class; // Affiche par exemple : Mickael Perraud } 30/03/2011 Mickaël Perraud 16
  17. 17. { Ce que PDO ne fait pas Ne fournit pas une abstraction de base de données : il ne réécrit pas le SQL Il némule pas des fonctionnalités manquantes 30/03/2011 Mickaël Perraud 17
  18. 18. { Zend_Db Composant daccès aux bases de données de Zend Framework Contient différents sous composants : Zend_Db_Adapter : abstraction de base de données Zend_Db_Select : abstraction de requête de type ”SELECT” Zend_Db_Table : ”Table Data Gateway” - http://martinfowler.com/eaaCatalog/tableDataGateway.html Zend_Db_Table_Row : ”Row Data Gateway” - http://martinfowler.com/eaaCatalog/rowDataGateway.html 30/03/2011 Mickaël Perraud 18
  19. 19. { Zend_Db_Adapter Surcharge PDO et certaines extensions (MySQLi, Oci8, Db2, Sqlsrv) en fournissant une interface commune Instanciation via la fabrique de Zend_Db : $db = Zend_Db::factory(Pdo_Mysql, array(host => localhost, username => mysql_user, password => mysql_password, dbname => mysql_database)); 30/03/2011 Mickaël Perraud 19
  20. 20. { Zend_Db_Adapter Exécution de requêtes préparées : $stmt = $db->query(SELECT * FROM utilisateurs WHERE id_utilisateur = ?, array($_GET[id])); Abstraction DML (”INSERT”, ”UPDATE”, ”DELETE”) : $id = $db->insert(utilisateurs, array(nom => Doe, prenom => John)); $db->update(utilisateurs, array(nom => Doe, prenom => Jane), array(id_utilisateur = ? => 2)); $db->delete(utilisateurs, array(id_utilisateur = ? => 2)); 30/03/2011 Mickaël Perraud 20
  21. 21. { Zend_Db : lecture des résultats Outre fetchAll() ou fetch() de PDO (renommé en fetchRow()), on dispose de : fetchAssoc() fetchCol() fetchOne() fetchPairs() 30/03/2011 Mickaël Perraud 21
  22. 22. { Zend_Db : autres fonctions Gestion du schéma : listTables() describeTable() Interface générique de gestion des transactions (beginTransaction(), commit(), rollback()) Abstraction de la clause limit() 30/03/2011 Mickaël Perraud 22
  23. 23. { Zend_Db_Select Abstraction DQL : permet de construire des requêtes de type ”SELECT” en PHP // Construire cette requête : // SELECT produit_id, produit_nom, prix // FROM "produits" // WHERE (prix > 100.00) // AND (prix < 500.00) $prixminimum = 100; $prixmaximum = 500; $select = $db->select() ->from(produits, array(produit_id, produit_nom, prix)) ->where(prix > ?, $prixminimum) ->where(prix < ?, $prixmaximum); 30/03/2011 Mickaël Perraud 23
  24. 24. { DoctrineDBAL Partie de Doctrine destinée à labstraction des bases de données : Plusieurs sous-composants : DoctrineDBALDriver : surcouche de PDO et quelques drivers (pas de SQL) DoctrineDBALPlatform : abstraction de la génération de requêtes et de fonctionnalités (SQL) DoctrineDBALSchema : abstraction de la gestion du schéma DoctrineDBALType : abstraction du typage avec mapping PHP 30/03/2011 Mickaël Perraud 24
  25. 25. { DoctrineDBAL Connexion : $connexion = DriverManager::getConnection(array(dbname => mysql_database, user => mysql_user, password => mysql_password, host => localhost, driver => pdo_mysql)); Exécution de requêtes préparées : $sql = "SELECT * FROM utilisateurs WHERE id = ? AND status = ?"; $stmt = $connexion->prepare($sql); $stmt->bindValue(1, $id); $stmt->bindValue(2, $status); $stmt->execute(); On retrouve une API de récupération de données très similaire à ce qui précède pour Zend_Db 30/03/2011 Mickaël Perraud 25
  26. 26. { DoctrineDBAL : transation Transaction imbriquées : // $connexion instanceof DoctrineDBALConnection $connexion->beginTransaction(); // 0 => 1, transaction "réelle" démarrée try { //... // nested transaction block, this might be in some other API/library code that is // unaware of the outer transaction. $connexion->beginTransaction(); // 1 => 2 try { //... $connexion->commit(); // 2 => 1 } catch (Exception $e) { $connexion->rollback(); // 2 => 1, transaction marquée pour annulation throw $e; } //... $connexion->commit(); // 1 => 0, transaction "réelle" confirmée } catch (Exception $e) { $connexion->rollback(); // 1 => 0, transaction "réelle" annulée throw $e; } 30/03/2011 Mickaël Perraud 26
  27. 27. { DoctrineDBAL : schéma manager listDatabases() listSequences() listTables() listTableColumns() listTableDetails() listTableForeignKeys() listTableIndexes() listViews() createSchema() 30/03/2011 Mickaël Perraud 27
  28. 28. { DoctrineDBAL : schéma génération Création table utilisateur : $schema = new DoctrineDBALSchemaSchema(); $maTable = $schema->createTable("utilisateurs"); $maTable->addColumn("id_utilisateur", "integer", array("unsigned" => true)); $maTable->addColumn("nom", "string", array("length" => 50)); $maTable->addColumn("prenom", "string", array("length" => 50)); $maTable->setPrimaryKey(array("id_utilisateur")); $schema->createSequence("utilisateurs_seq"); $myForeign = $schema->createTable("commentaires"); $myForeign->addColumn("id_commentaire", "integer"); $myForeign->addColumn("utilisateur_id", "integer"); $myForeign->addForeignKeyConstraint($myTable, array("utilisateur_id"), array("id_utilisateur"), array("onUpdate" => "CASCADE")); // Récupérer les requêtes pour générer le schéma $queries = $schema->toSql($myPlatform); // Récupérer les requêtes pour effacer le schéma $dropSchema = $schema->toDropSql($myPlatform); 30/03/2011 Mickaël Perraud 28
  29. 29. { Ceux quil ne faut pas oublier ADOdb : 5.11 (PHP 5) PEAR::MDB2 : 2.5.0 en beta (PHP 5.3+) 30/03/2011 Mickaël Perraud 29
  30. 30. { ZendDb 2.0 ZendDbAdapter : ajout plugin (pre- post-connect), suppression du SQL pur ZendDbQuery : abstraction DML, DQL, ainsi que DDL (”alter”, ”create”, ”drop”) et DCL (”commit”, ”rollback”, ”savepoint”), supporte ANSI ainsi que les dialectes des SGBD ZendDbResultSet : modélisation des résultats ZendDbMetadata : gestion du schéma http://framework.zend.com/wiki/display/ZFDEV2/Zend+Db+2.0+Requirements 30/03/2011 Mickaël Perraud 30

×