SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
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 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).


    29 juin 2011        Mickaël Perraud                   2
Accès aux bases de données
         relationnelles et ORM en PHP



3 interventions :
   Présentation de différents DBAL
   Présentation de l'ORM Doctrine2
   Présentation de Pomm



    29 juin 2011    Mickaël Perraud     3
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 l'aide à la traduction et propose les versions déconnectées
   de la documentation PDF / CHM
  Vice-trésorier AFUP 2011
                                                @mikaelkael / http://mikaelkael.fr



  29 juin 2011                Mickaël Perraud                                   4
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'];
   }




     29 juin 2011                      Mickaël Perraud                            5
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());
      }



     29 juin 2011                       Mickaël Perraud                              6
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':
                        //...




      29 juin 2011                      Mickaël Perraud                            7
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 d'abstraction à l'accès aux
données
Plus sécurisé (si bien utilisé)

   29 juin 2011       Mickaël Perraud           8
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
                    )
                      */



     29 juin 2011                    Mickaël Perraud       9
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


     29 juin 2011                     Mickaël Perraud                                       10
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();



            L'assignation peut être nommée (ci-dessus) ou
              numérique


       29 juin 2011                     Mickaël Perraud                                     11
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
                      )




     29 juin 2011                     Mickaël Perraud                     12
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"
                    }

     29 juin 2011                  Mickaël Perraud   13
PDO : lecture des résultats



     Le meilleur pour la fin ?
               PDO::FETCH_CLASS
     Prend un résultat et le retourne sous la forme d'une
       classe
     On peut instancier la classe directement par PDO




29 juin 2011               Mickaël Perraud                  14
PDO::FETCH_CLASS

                            class Utilisateur {
                                private $_nom;
                                private $_prenom;
                                public function __set($attribut, $valeur)
                                {
                                    $this->{"set".ucfirst($attribut)} = $valeur;
                                }
                                public function setNom($nom)
                                {
Notre classe :                      $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;
                                }
                            }

      29 juin 2011               Mickaël Perraud                                   15
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
          }




    29 juin 2011                      Mickaël Perraud                     16
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




   29 juin 2011              Mickaël Perraud                17
Zend_Db


Composant d'accè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




     29 juin 2011                 Mickaël Perraud                18
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'));




     29 juin 2011                      Mickaël Perraud                                 19
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));


     29 juin 2011                       Mickaël Perraud                              20
Zend_Db : lecture des résultats


Outre fetchAll() ou fetch() de PDO (renommé en fetchRow()),
on dispose de :
          fetchAssoc()
          fetchCol()
          fetchOne()
          fetchPairs()




     29 juin 2011        Mickaël Perraud                 21
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()




     29 juin 2011           Mickaël Perraud       22
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);




     29 juin 2011                      Mickaël Perraud                        23
DoctrineDBAL


Partie de Doctrine destinée à l'abstraction 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




      29 juin 2011                Mickaël Perraud                                24
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



     29 juin 2011                       Mickaël Perraud                                    25
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;
     }


     29 juin 2011                      Mickaël Perraud                                   26
DoctrineDBAL : schéma manager


       listDatabases()
       listSequences()
       listTables()
       listTableColumns()
       listTableDetails()
       listTableForeignKeys()
       listTableIndexes()
       listViews()
       createSchema()

29 juin 2011                Mickaël Perraud   27
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);




      29 juin 2011                     Mickaël Perraud                              28
Ceux qu'il ne faut pas oublier




     ADOdb : 5.11 (PHP 5)
     PEAR::MDB2 : 2.5.0 en beta (PHP 5.3+)




29 juin 2011            Mickaël Perraud      29
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




29 juin 2011                         Mickaël Perraud                             30

Contenu connexe

Tendances

PHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesPHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesJean Michel
 
Chapitre 2 classe et objet
Chapitre 2   classe et objetChapitre 2   classe et objet
Chapitre 2 classe et objetAmir Souissi
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationECAM Brussels Engineering School
 
Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Claude Falguiere
 
.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHPAbdoulaye Dieng
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantHugo Hamon
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbcKarim Amane
 
Php 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPhp 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPierre Faure
 

Tendances (16)

Marzouk collection-map
Marzouk collection-mapMarzouk collection-map
Marzouk collection-map
 
Gestion de formulaires en PHP
Gestion de formulaires en PHPGestion de formulaires en PHP
Gestion de formulaires en PHP
 
Ch03
Ch03Ch03
Ch03
 
Python avancé : Tuple et objet
Python avancé : Tuple et objetPython avancé : Tuple et objet
Python avancé : Tuple et objet
 
PHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulairesPHP #3 : tableaux & formulaires
PHP #3 : tableaux & formulaires
 
Chapitre 2 classe et objet
Chapitre 2   classe et objetChapitre 2   classe et objet
Chapitre 2 classe et objet
 
Syntaxe du langage PHP
Syntaxe du langage PHPSyntaxe du langage PHP
Syntaxe du langage PHP
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulation
 
Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012
 
Structure de données en PHP
Structure de données en PHPStructure de données en PHP
Structure de données en PHP
 
.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 Performant
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbc
 
Python avancé : Classe et objet
Python avancé : Classe et objetPython avancé : Classe et objet
Python avancé : Classe et objet
 
Php 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPhp 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVC
 
Cours PHP avancé
Cours PHP avancéCours PHP avancé
Cours PHP avancé
 

En vedette

Polla mundial1
Polla mundial1Polla mundial1
Polla mundial1Cristian
 
Tarea 1.modulo 3
Tarea 1.modulo 3Tarea 1.modulo 3
Tarea 1.modulo 3osterizjjoc
 
Skills&qualities presentation
Skills&qualities presentationSkills&qualities presentation
Skills&qualities presentationsalexa86
 
La produccion del arroz
La produccion del arrozLa produccion del arroz
La produccion del arrozmaicol
 
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...Ralph J. Schiel
 
Diseño de pagina web dedicada a las ciencias
Diseño de pagina web dedicada a las cienciasDiseño de pagina web dedicada a las ciencias
Diseño de pagina web dedicada a las cienciasferiacoleman2010
 
Hotel oder wohnmobil
Hotel oder wohnmobilHotel oder wohnmobil
Hotel oder wohnmobilvereggewe
 
Lenguajes de programacion
Lenguajes de programacionLenguajes de programacion
Lenguajes de programacionjuanjokobrax
 
Informatica educativa
Informatica educativaInformatica educativa
Informatica educativaupc
 
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...Javier Hernandez-Acosta
 

En vedette (20)

Zf2 ce-qui-va-changer
Zf2 ce-qui-va-changerZf2 ce-qui-va-changer
Zf2 ce-qui-va-changer
 
Polla mundial1
Polla mundial1Polla mundial1
Polla mundial1
 
Tarea 1.modulo 3
Tarea 1.modulo 3Tarea 1.modulo 3
Tarea 1.modulo 3
 
Skills&qualities presentation
Skills&qualities presentationSkills&qualities presentation
Skills&qualities presentation
 
Presentac..[1]
Presentac..[1]Presentac..[1]
Presentac..[1]
 
3-Cm24
3-Cm243-Cm24
3-Cm24
 
La produccion del arroz
La produccion del arrozLa produccion del arroz
La produccion del arroz
 
Buscadores
BuscadoresBuscadores
Buscadores
 
Thiết kế Website chuẩn seo
Thiết kế Website chuẩn seoThiết kế Website chuẩn seo
Thiết kế Website chuẩn seo
 
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...
naturblau Nachhaltigkeit Kommunikation Marke Strategie Jungunternehmertag Vol...
 
Diseño de pagina web dedicada a las ciencias
Diseño de pagina web dedicada a las cienciasDiseño de pagina web dedicada a las ciencias
Diseño de pagina web dedicada a las ciencias
 
Hotel oder wohnmobil
Hotel oder wohnmobilHotel oder wohnmobil
Hotel oder wohnmobil
 
Lenguajes de programacion
Lenguajes de programacionLenguajes de programacion
Lenguajes de programacion
 
Informatica educativa
Informatica educativaInformatica educativa
Informatica educativa
 
Esforse
EsforseEsforse
Esforse
 
Wiki präsentation
Wiki präsentationWiki präsentation
Wiki präsentation
 
Martha martinez
Martha martinezMartha martinez
Martha martinez
 
Social Media und Recht
Social Media und RechtSocial Media und Recht
Social Media und Recht
 
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...
Una aproximación al rendimiento cultural - Inter-acciones Creativas 2013 (Jav...
 
Trabajo
TrabajoTrabajo
Trabajo
 

Similaire à Présentation de DBAL en PHP (Nantes)

Présentation de DBAL en PHP
Présentation de DBAL en PHPPrésentation de DBAL en PHP
Présentation de DBAL en PHPMickael Perraud
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Engineor
 
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairie
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairieCours PHP PDO intégrale afin de mieux appréhender la nouvelle librairie
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairieafdoumbia
 
Meet up symfony 11 octobre 2016 - Les formulaire
Meet up symfony 11 octobre 2016 - Les formulaireMeet up symfony 11 octobre 2016 - Les formulaire
Meet up symfony 11 octobre 2016 - Les formulaireJulien Vinber
 
PHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaPHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaMehdi EL KRARI
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web5pidou
 
Développement Web- PHP (partie II).pdf
Développement Web- PHP (partie II).pdfDéveloppement Web- PHP (partie II).pdf
Développement Web- PHP (partie II).pdfYasushiTsubakik
 
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...Fabien Potencier
 
Programmation STUPID vs SOLID (PHP Meetup)
Programmation STUPID vs SOLID (PHP Meetup)Programmation STUPID vs SOLID (PHP Meetup)
Programmation STUPID vs SOLID (PHP Meetup)Arnaud Langlade
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Jean-Michel Doudoux
 
"Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?""Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?"o2sources
 
Les principes de base de PHP
 Les principes de base de PHP  Les principes de base de PHP
Les principes de base de PHP EL JAOUARI Ahmed
 

Similaire à Présentation de DBAL en PHP (Nantes) (20)

Présentation de DBAL en PHP
Présentation de DBAL en PHPPrésentation de DBAL en PHP
Présentation de DBAL en PHP
 
Client base de données en PHP5
Client base de données en PHP5Client base de données en PHP5
Client base de données en PHP5
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !
 
Php Data Object
Php Data ObjectPhp Data Object
Php Data Object
 
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairie
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairieCours PHP PDO intégrale afin de mieux appréhender la nouvelle librairie
Cours PHP PDO intégrale afin de mieux appréhender la nouvelle librairie
 
Playing With PHP 5.3
Playing With PHP 5.3Playing With PHP 5.3
Playing With PHP 5.3
 
Php1
Php1Php1
Php1
 
De legacy à symfony
De legacy à symfonyDe legacy à symfony
De legacy à symfony
 
Meet up symfony 11 octobre 2016 - Les formulaire
Meet up symfony 11 octobre 2016 - Les formulaireMeet up symfony 11 octobre 2016 - Les formulaire
Meet up symfony 11 octobre 2016 - Les formulaire
 
PHP 5 pour les développeurs Java
PHP 5 pour les développeurs JavaPHP 5 pour les développeurs Java
PHP 5 pour les développeurs Java
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web
 
Développement Web- PHP (partie II).pdf
Développement Web- PHP (partie II).pdfDéveloppement Web- PHP (partie II).pdf
Développement Web- PHP (partie II).pdf
 
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...
Découpler votre code pour assurer la réutilisabilité et la maintenabilite ...
 
POO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdfPOO-JAVA-partie-1.pdf
POO-JAVA-partie-1.pdf
 
Programmation STUPID vs SOLID (PHP Meetup)
Programmation STUPID vs SOLID (PHP Meetup)Programmation STUPID vs SOLID (PHP Meetup)
Programmation STUPID vs SOLID (PHP Meetup)
 
Héritage et redéfinition de méthode
Héritage et redéfinition de méthodeHéritage et redéfinition de méthode
Héritage et redéfinition de méthode
 
Ce bon vieux propel
Ce bon vieux propelCe bon vieux propel
Ce bon vieux propel
 
Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017Java 9 modulo les modules devoxx fr 2017
Java 9 modulo les modules devoxx fr 2017
 
"Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?""Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?"
 
Les principes de base de PHP
 Les principes de base de PHP  Les principes de base de PHP
Les principes de base de PHP
 

Plus de Mickael Perraud

Découvrez le noyau d'internationalisation du Zend Framework
Découvrez le noyau d'internationalisation du Zend FrameworkDécouvrez le noyau d'internationalisation du Zend Framework
Découvrez le noyau d'internationalisation du Zend FrameworkMickael Perraud
 
Introduction à Zend Framework 2
Introduction à Zend Framework 2Introduction à Zend Framework 2
Introduction à Zend Framework 2Mickael Perraud
 
Développement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkDéveloppement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkMickael Perraud
 
Tester les applications Zend Framework
Tester les applications Zend FrameworkTester les applications Zend Framework
Tester les applications Zend FrameworkMickael Perraud
 
Tirer parti des décorateurs de Zend_Form
Tirer parti des décorateurs de Zend_FormTirer parti des décorateurs de Zend_Form
Tirer parti des décorateurs de Zend_FormMickael Perraud
 
Quoi de neuf dans Zend Framework 1.10 ?
Quoi de neuf dans Zend Framework 1.10 ?Quoi de neuf dans Zend Framework 1.10 ?
Quoi de neuf dans Zend Framework 1.10 ?Mickael Perraud
 

Plus de Mickael Perraud (6)

Découvrez le noyau d'internationalisation du Zend Framework
Découvrez le noyau d'internationalisation du Zend FrameworkDécouvrez le noyau d'internationalisation du Zend Framework
Découvrez le noyau d'internationalisation du Zend Framework
 
Introduction à Zend Framework 2
Introduction à Zend Framework 2Introduction à Zend Framework 2
Introduction à Zend Framework 2
 
Développement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend FrameworkDéveloppement sécurisé d'applications avec Zend Framework
Développement sécurisé d'applications avec Zend Framework
 
Tester les applications Zend Framework
Tester les applications Zend FrameworkTester les applications Zend Framework
Tester les applications Zend Framework
 
Tirer parti des décorateurs de Zend_Form
Tirer parti des décorateurs de Zend_FormTirer parti des décorateurs de Zend_Form
Tirer parti des décorateurs de Zend_Form
 
Quoi de neuf dans Zend Framework 1.10 ?
Quoi de neuf dans Zend Framework 1.10 ?Quoi de neuf dans Zend Framework 1.10 ?
Quoi de neuf dans Zend Framework 1.10 ?
 

Présentation de DBAL en PHP (Nantes)

  • 1. Accès aux bases de données relationnelles et ORM en PHP
  • 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 d'abstraction de base de données) ou les ORM (Object Relational Mapping ou mapping objet-relationnel). 29 juin 2011 Mickaël Perraud 2
  • 3. Accès aux bases de données relationnelles et ORM en PHP 3 interventions : Présentation de différents DBAL Présentation de l'ORM Doctrine2 Présentation de Pomm 29 juin 2011 Mickaël Perraud 3
  • 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 l'aide à la traduction et propose les versions déconnectées de la documentation PDF / CHM Vice-trésorier AFUP 2011 @mikaelkael / http://mikaelkael.fr 29 juin 2011 Mickaël Perraud 4
  • 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']; } 29 juin 2011 Mickaël Perraud 5
  • 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()); } 29 juin 2011 Mickaël Perraud 6
  • 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': //... 29 juin 2011 Mickaël Perraud 7
  • 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 d'abstraction à l'accès aux données Plus sécurisé (si bien utilisé) 29 juin 2011 Mickaël Perraud 8
  • 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 ) */ 29 juin 2011 Mickaël Perraud 9
  • 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 29 juin 2011 Mickaël Perraud 10
  • 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(); L'assignation peut être nommée (ci-dessus) ou numérique 29 juin 2011 Mickaël Perraud 11
  • 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 ) 29 juin 2011 Mickaël Perraud 12
  • 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" } 29 juin 2011 Mickaël Perraud 13
  • 14. PDO : lecture des résultats Le meilleur pour la fin ? PDO::FETCH_CLASS Prend un résultat et le retourne sous la forme d'une classe On peut instancier la classe directement par PDO 29 juin 2011 Mickaël Perraud 14
  • 15. PDO::FETCH_CLASS class Utilisateur { private $_nom; private $_prenom; public function __set($attribut, $valeur) { $this->{"set".ucfirst($attribut)} = $valeur; } public function setNom($nom) { Notre classe : $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; } } 29 juin 2011 Mickaël Perraud 15
  • 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 } 29 juin 2011 Mickaël Perraud 16
  • 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 29 juin 2011 Mickaël Perraud 17
  • 18. Zend_Db Composant d'accè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 29 juin 2011 Mickaël Perraud 18
  • 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')); 29 juin 2011 Mickaël Perraud 19
  • 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)); 29 juin 2011 Mickaël Perraud 20
  • 21. Zend_Db : lecture des résultats Outre fetchAll() ou fetch() de PDO (renommé en fetchRow()), on dispose de : fetchAssoc() fetchCol() fetchOne() fetchPairs() 29 juin 2011 Mickaël Perraud 21
  • 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() 29 juin 2011 Mickaël Perraud 22
  • 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); 29 juin 2011 Mickaël Perraud 23
  • 24. DoctrineDBAL Partie de Doctrine destinée à l'abstraction 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 29 juin 2011 Mickaël Perraud 24
  • 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 29 juin 2011 Mickaël Perraud 25
  • 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; } 29 juin 2011 Mickaël Perraud 26
  • 27. DoctrineDBAL : schéma manager listDatabases() listSequences() listTables() listTableColumns() listTableDetails() listTableForeignKeys() listTableIndexes() listViews() createSchema() 29 juin 2011 Mickaël Perraud 27
  • 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); 29 juin 2011 Mickaël Perraud 28
  • 29. Ceux qu'il ne faut pas oublier ADOdb : 5.11 (PHP 5) PEAR::MDB2 : 2.5.0 en beta (PHP 5.3+) 29 juin 2011 Mickaël Perraud 29
  • 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 29 juin 2011 Mickaël Perraud 30