SlideShare une entreprise Scribd logo
Ce bon vieux Propel
    RDV AFUP, 30 mars 2011
      François Zaninotto
ActiveRecord

                                                         $author = new Author();
                                                         $author->setFirstName('Leo');
   author                       book                     $author->setLastName('Tolstoi');
                                                         $author->save();
   id                           id
   last_name                  * title                    $book = new Book();
   first_name                    author_id                $book->setTitle('War And Peace');
                                                         $book->setISBN('0143039997');
                                                         $book->setPrice(12.99);
                                                         $book->setAuthor($author);
                                                         $book->save();




Propel est une implémentation d’ActiveRecord
Un enregistrement d’une table = Un objet
On abstrait le SQL derrière la manipulation d’objets en PHP
Getter et Setter pour chaque colonne, et pour les FK aussi
Persistance via save() - et delete() bien sûr
Propel génère les classes Author et Book à partir de la BDD - ou à partir d’un schema
INSERT INTO `author` (`first_name`, `last_name`)
        VALUES ('Leo', 'Tolstoi');


 INSERT INTO `book` (`title`, `ISBN`, `price`, `author_id`)
        VALUES ('War And Peace', '0143039997', 12.99, 123);




Mais le SQL est bien là, généré par Propel.
Il est toujours disponible à un clic de souris (dans un fichier de log, ou dans une propriété de l’objet de connexion).
Notez que Propel gère automatiquement la clé étrangère author_id, et que les identifiants primaires n’apparaissent pas dans le
code PHP.
Pour la quincaillerie DBAL, c’est PDO qui est aux commandes - un PDO surboosté
class Author extends BaseAuthor
 {
   public function getFullName()
   {
     if ($this->getFirstName() && $this->getLastName()) {
       return $this->getFirstName().' '.$this->getLastName();
     }
     if ($this->getLastName()) {
       return $this->getLastName();
     }
     if ($this->getFirstName()) {
       return $this->getFirstName();
     }
     return 'Anonymous Coward';
 }

 echo $author->getFullName(); // Leo Tolstoi



Les classes ActiveRecord sont l’endroit idéal pour stocker de la logique métier.
Cela rend les méthodes réutilisables, testables, lisibles.
ActiveRecord est
          un Design Pattern
               http://martinfowler.com/
             eaaCatalog/activeRecord.html




Propel n’a rien inventé. ActiveRecord est un pattern connu depuis longtemps, et utilisé dans 80% des ORM.
Ces n’est pas ça qui fait la différence entre Propel et les autres ORM
Rapide
                                               Professionnel
                                               Ergonomique
                                                   IDE friendly
Il y a quatre éléments qui font vraiment la différence. Si vous ne devez retenir qu’une seule slide.
1 - Rapide: pour installer, pour exécuter, et pour apprendre les bases de Propel, il vous faudra une demi journée.
2 - Professionnel, car après plus de 7 ans d’existence et 5000 unit tests, Propel tient bon. Seul Doctrine arrive au même niveau de professionnalisme ; les autres
ORMs sont loin derrière.
3 - Ergonomique, car Propel fait toujours le pari de la facilité d’utilisation. Propel prend en charge toutes les tâches évidentes, et gère sans configuration
particulière les 80% des cas les plus courants.
4 - IDE Friendly, car la génération de code donne aux IDE la visibilité de toutes les méthodes, et le phpDoc a été spécialement pensée pour aider les
développeurs.
ActiveQuery


Comme pour les objets ActiveRecord, Propel génère une classe de requête par table.
Cela permet de proposer des raccourcis de requêtage, et d’encapsuler la logique métier dans des classes de requêtage.
On a donc une véritable API objet pour requêter un entrepôt... une BDD OO?
// trouver un objet avec sa clé primaire
  $author = AuthorQuery::create()->findPk(123);

  // conditions sur les colonnes
  $book = BookQuery::create()
    ->filterByTitle('War And Peace')
    ->findOne();

  // raccourcis
  $book = BookQuery::create()
    ->findOneByTitle('War And Peace');




create() est une factory qui renvoie un objet déterminé, ça aide beaucoup l’IDE pour la complétion.
findPk() et findOne() renvoient un objet ActiveRecord. find() renvoie une collection.
filterByXXX() est la façon de dire WHERE à Propel. On peut combiner plusieurs filtres.
Les classes de requêtes sont truffées de raccourcis qui facilitent la vie, comme le findOneByXXX() qui est une méthode magique...
mais qui apparait dans l’IDE.
// conditions intelligentes
 $author = AuthorQuery::create()
   ->filterByTitle('War%')
   ->findOne();

 $book = BookQuery::create()
   ->filterByAuthor($author)
   ->find();

 $books = BookQuery::create()
   ->filterByPrice(array('min'=>10, 'max'=>20))
   ->find();



La connaissance du type de la colonne au moment de la génération des méthodes de filtre permet de leur ajouter des capacités
particulières.
On peut ainsi filtrer sur une chaine avec des jokers, sur une intervalle pour un nombre.
Les clés étrangères sont vues comme des relations, et Propel génère des raccourcis supplémentaires. On peut ainsi filtrer sur des
objets, sans connaitre les colonnes impliquées dans une clé étrangère.
SELECT * FROM `book` WHERE `book.title` LIKE 'War%';

   SELECT * FROM `book` WHERE `book.author_id` = 123;

   SELECT * FROM `book`
     WHERE `book.price` > 10
     AND `book.price` < 20;




Les SQL généré est toujours à un clic de souris.
Le binding est fait via PDO, en fonction du type de la colonne.
Vous êtes donc à l’abri des injections SQL
Petit détail: le SQL montré ici est celui que Propel génère pour MySQL. Pour PostgreSQL, SQLite, SQLServer, et Oracle, Propel
génère un code différent et optimisé pour chaque de base.
class BookQuery extends BaseBookQuery
    {
      const CHEAP_LEVEL = 8;

        public function cheap($maxPrice = self::CHEAP_LEVEL)
        {
          $this->filterByPrice(array('max' => $maxPrice));
          return $this;
        }
    }

    // trouver les éditions bon marché de 'War And Peace',
    // classées par titre
    $books = BookQuery::create()
      ->filterByTitle('War%')
      ->cheap()
      ->orderByTitle()
      ->find();


Les classes ActiveQuery sont l’endroit idéal pour stocker de la logique métier.
Cela rend les méthodes réutilisables, testables, lisibles.
On crée un DSL, un Domain-Specific Language, pour son modèle.
Ca ne vous rappelle rien ? Eh oui, ce sont les mêmes principes que pour ActiveRecord.
// trouver les auteurs ayant le prénom 'Leo'
    $authors = AuthorQuery::create()
      ->filterByFirstName('Leo')
      ->find();
    $books = BookQuery::create()
      ->filterByAuthor($authors)
      ->find();

    // la même chose, en une seule requête
    $books = BookQuery::create()
      ->useAuthorQuery()
        ->filterByFirstName('Leo')
      ->endUse()
      ->orderByTitle()
      ->find();



Queries embarquées: filterByFirstName() est une méthode de l’objet AuthorQuery. On peut l’utiliser dans l’objet BookQuery par
une query embarquée, que Propel traduit par un bon vieux Join.
Cela vous permet donc d’encapsuler la logique métier dans la bonne classe, et de la rendre réutilisable dans les objets liés
SELECT * FROM `book`
    LEFT JOIN `author` ON `book.author_id` = `author.id`
    WHERE `author.first_name` = 'Leo'
    ORDER BY `book.title` ASC




Propel connait la relation Book <-> Author, il sait donc écrire le join tout seul.
En fait, toute requête SQL peut être écrite comme une suite d’appels de méthode sur un objet ActiveQuery. Mais ce n’est pas là
l’essentiel: Dans Propel, on ne traduit pas du SQL en objet, on manipule directement des objets. A partir de maintenant, fini le
SQL (même si vous savez qu’il est toujours derrière).
Full Featured

ActiveRecord et ActiveQuery sont la partie immergée de l’iceberg. Propel offre bien plus - voyez cette liste non exhaustive, qui montre que


                                 Hydratation combinée
Propel est un ORM full-featured. Seul Doctrine 1 arrive à ce niveau.
L’hydratation, c’est le fait de peupler un objet avec des données qui viennent de la base. L’hydratation transforme un objet vide (sec) en objet
imbibé de données venant d’un resultset.
Reverse engineering
  Hydratation            Moteur
   combinée           d’évènements
                                           Clés composites
 Hydratation sur    Liaisons 1-1 et n-n
                                               Indexes
   demande
                       Collections
                                              Vues SQL
   Validators
                          Pager
                                             Autoloading
Héritage de table
                        Migrations
                                             Connections
 Import/Export                                multiples
XML,YAML, JSON,        Namespaces
     CSV
                                              Query log
                       FK virtuelles
Types Blob, Enum,
 Boolean, Array,                               Profiler
                       Transactions
     Object             imbriquées
                                           Introspection au
 Colonnes Lazy                                 runtime
                    Réplication master-
    loadées                slave
Behaviors
       timestampable                                               i18n

       sluggable                                                   concrete_inheritance

       sortable                                                    aggregate_column

       versionable                                                 query_cache

       soft_delete                                                 alternative_coding_standards

       nested_set                                                  ... et contributions tierces


Propel offre ce que tout bon ORM doit offrir, une bibliothèque de «comportements» d’objets métiers prédéveloppés, que l’on
peut activer à loisir.
query_cache et alternative_coding_standards ne sont pas vraiment des «comportements», mais ça montre que le système de
behaviors de Propel est plus un système de plugins, qui permet de modifier le code généré à loisir
Propel est RAPIDE
                            0x                   2,5x                   5,0x                  7,5x                10,0x               12,5x

                PDO                                                                                      Scénario 1: findPk
                                                                                                         Scénario 2: hydrate
       Propel 1.6

        Doctrine2

    Doctrine 1.2


                            http://code.google.com/p/php-orm-benchmark/

Selon les scénarios, Propel est entre 1,5 fois et 5 fois plus lent que pdo seul. Ca peut paraître beaucoup, mais c’est à comparer au code
boilerplate que vous avez pu écrire dans vos applications pour effectuer le binding des variables, tester les cas limites, chercher la bonne
connexion, logguer les résultats... Etes-vous sûrs que ce code est rapide ? Propel, lui, cherche avant tout la rapidité. Et ça se voit, quand on le
compare aux autres ORMs phares en PHP.
Le benchmark qui permet d’arriver aux résultats ci-dessus est public, testez-le !
Propel est
                              PROFESSIONNEL
              Tests unitaires                                                    Communauté

              BC depuis la 1.3                                                   Maj tous les mois

              Configurable                                                        Bug tracker public

              Documentation                                                      Utilisé par des
                                                                                 professionnels
              Ecosystème (behaviors,
              DBDesigner, plugins)                                               License MIT


Propel a tout ce qu’il faut pour faire une application qui tient, une application qui dure, une application qui grandit. PHP n’est pas forcément le
langage dans lequel on trouve le plus de librairies professionnelles. Propel en est une. Il a été choisi par de nombreuses sociétés parce qu’il est
professionnel.
Chaque patch contient des tests et de la doc - c’est du DDD, documentation-driven development (cherchez le terme pour rire un peu). La doc,
c’est mon dada - j’ai déjà écrit deux bouquins. Propel, c’est sept ans d’efforts.
Propel est
                          ERGONOMIQUE

        $book->setCreatedAt(time());
        $book->setCreatedAt('now');
        $book->setCreatedAt('2011-03-30 20:15');
        $book->setCreatedAt(new DateTime());




C’est à Propel de s’adapter à vous, pas à vous de vous adapter à Propel. Zéro configuration pour commencer. Une seule
dépendance externe: Phing. Mais si vous utilisez symfony ou Symfony2, le setup est instantané et Phing est livré avec. Peu
d’objets à manipuler (ActiveRecord, ActiveQuery, connection), d’où un apprentissage très rapide. Pas de magie: le code est généré
et accessible. phpDoc complète.
Propel est IDE FRIEDNLY




Les IDE avec autocomplétion tirent parti des information générées par Propel au format phpDoc pour faciliter encore davantage
la vide des développeurs.
ActiveRecord Not Dead




             DataMapper                                                        ActiveRecord

N’écoutez pas ceux qui vous disent qu’ActiveRecord est mauvais. C’est juste une histoire de goût. ActiveRecord permet de tester
son modèle. La preuve: Propel a plus de 5000 tests. L’héritage n’est pas un problème puisque les behaviors permettent la
réutilisation horizontale. Quant à la performance, ça n’a jamais été un problème que pour les ActiveRecord n’utilisant pas de
génération de code.
Pour comparer, EntityManager, c’est le goût de la pureté de Java. ActiveRecord, c’est le goût de la facilité de Ruby et Rails. Les
deux viennent de Fowler.
Merci
François Zaninotto, lead dev Propel
  Site: http://www.propelorm.org
 Blog: http://propel.posterous.com
       Twitter: @francoisz
  eTF1 recrute, contactez-moi !

Contenu connexe

Tendances

Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4
halleck45
 
Scrapez facilement et gratuitement
Scrapez facilement et gratuitementScrapez facilement et gratuitement
Scrapez facilement et gratuitement
Madeline Pinthon
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
Jean-Michel Doudoux
 
.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP
Abdoulaye Dieng
 
Présentation de ECMAScript 6
Présentation de ECMAScript 6Présentation de ECMAScript 6
Présentation de ECMAScript 6
Julien CROUZET
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDO
Abdoulaye Dieng
 
Introduction au Jquery
Introduction au JqueryIntroduction au Jquery
Introduction au Jquery
Abdoulaye Dieng
 
Exploiter php 5
Exploiter php 5Exploiter php 5
Exploiter php 5
halleck45
 
Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016
François Sarradin
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3
Eddy RICHARD
 
Apprendre Solr en deux heures
Apprendre Solr en deux heuresApprendre Solr en deux heures
Apprendre Solr en deux heures
Saïd Radhouani
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
Olivier Le Goaër
 
Javascript pour le développeur Java
Javascript pour le développeur JavaJavascript pour le développeur Java
Javascript pour le développeur Java
jollivetc
 
Requêtes HTTP synchrones et asynchrones
Requêtes HTTPsynchrones et asynchronesRequêtes HTTPsynchrones et asynchrones
Requêtes HTTP synchrones et asynchrones
Abdoulaye Dieng
 
Objet Direct Formation JPA Hibernate
Objet Direct Formation JPA HibernateObjet Direct Formation JPA Hibernate
Objet Direct Formation JPA Hibernate
formationobjetdirect
 
Meetup pg recherche fulltext ES -> PG
Meetup pg recherche fulltext ES -> PGMeetup pg recherche fulltext ES -> PG
Meetup pg recherche fulltext ES -> PG
Louise Grandjonc
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
Kristen Le Liboux
 
Introduction à jQuery
Introduction à jQueryIntroduction à jQuery
Introduction à jQuery
Abdoulaye Dieng
 
Qui a laissé son mot de passe dans le code
Qui a laissé son mot de passe dans le codeQui a laissé son mot de passe dans le code
Qui a laissé son mot de passe dans le code
Damien Seguy
 

Tendances (20)

Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4
 
Scrapez facilement et gratuitement
Scrapez facilement et gratuitementScrapez facilement et gratuitement
Scrapez facilement et gratuitement
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
 
.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP.php1 : les fondamentaux du PHP
.php1 : les fondamentaux du PHP
 
Présentation de ECMAScript 6
Présentation de ECMAScript 6Présentation de ECMAScript 6
Présentation de ECMAScript 6
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDO
 
Introduction au Jquery
Introduction au JqueryIntroduction au Jquery
Introduction au Jquery
 
Exploiter php 5
Exploiter php 5Exploiter php 5
Exploiter php 5
 
Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016
 
PHP 7 et Symfony 3
PHP 7 et Symfony 3PHP 7 et Symfony 3
PHP 7 et Symfony 3
 
Apprendre Solr en deux heures
Apprendre Solr en deux heuresApprendre Solr en deux heures
Apprendre Solr en deux heures
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
Javascript pour le développeur Java
Javascript pour le développeur JavaJavascript pour le développeur Java
Javascript pour le développeur Java
 
Requêtes HTTP synchrones et asynchrones
Requêtes HTTPsynchrones et asynchronesRequêtes HTTPsynchrones et asynchrones
Requêtes HTTP synchrones et asynchrones
 
Objet Direct Formation JPA Hibernate
Objet Direct Formation JPA HibernateObjet Direct Formation JPA Hibernate
Objet Direct Formation JPA Hibernate
 
Meetup pg recherche fulltext ES -> PG
Meetup pg recherche fulltext ES -> PGMeetup pg recherche fulltext ES -> PG
Meetup pg recherche fulltext ES -> PG
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Cours php
Cours phpCours php
Cours php
 
Introduction à jQuery
Introduction à jQueryIntroduction à jQuery
Introduction à jQuery
 
Qui a laissé son mot de passe dans le code
Qui a laissé son mot de passe dans le codeQui a laissé son mot de passe dans le code
Qui a laissé son mot de passe dans le code
 

En vedette

Practica de word
Practica de wordPractica de word
Practica de word
mariajara
 
Charte qualité-elcofrance
Charte qualité-elcofranceCharte qualité-elcofrance
Charte qualité-elcofrance
ElcoFrance Assurance Villeparisis
 
Estas son nuestras obras de arte
Estas son nuestras obras de arteEstas son nuestras obras de arte
Estas son nuestras obras de arte
Eli Mar Jiménez
 
Cómo usar Slideshare
Cómo usar SlideshareCómo usar Slideshare
Ampliación medidas cautelares Cidh
Ampliación medidas cautelares CidhAmpliación medidas cautelares Cidh
Ampliación medidas cautelares Cidh
Defensoría Del Pueblo Ecuador
 
Bienvenue Au Maroc
Bienvenue Au MarocBienvenue Au Maroc
Bienvenue Au Maroc
jwilili
 
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
Raphaël Fétique
 
Acdc
AcdcAcdc
Presentación Edad Media.
Presentación Edad Media.Presentación Edad Media.
Presentación Edad Media.
mbelgon
 
Fix "error de memoria tarjeta"
Fix "error de memoria tarjeta"Fix "error de memoria tarjeta"
Fix "error de memoria tarjeta"
foto recuperacion
 
Presentación Robótica
Presentación RobóticaPresentación Robótica
Presentación Robótica
renediazreta
 
Pronunciamiento dpe con respecto al referendum ante cc
Pronunciamiento dpe con respecto al referendum ante ccPronunciamiento dpe con respecto al referendum ante cc
Pronunciamiento dpe con respecto al referendum ante cc
Defensoría Del Pueblo Ecuador
 
Si tienes una idea empréndela, y verás...
Si tienes una idea empréndela, y verás...Si tienes una idea empréndela, y verás...
Si tienes una idea empréndela, y verás...
Sergio Montoro Ten
 
Presentación Video
Presentación VideoPresentación Video
Presentación Video
Pablo Oneri
 
Virtualización - Evolución hacia el IT Ágil
Virtualización - Evolución hacia el IT ÁgilVirtualización - Evolución hacia el IT Ágil
Virtualización - Evolución hacia el IT Ágil
Pablo Carlier
 

En vedette (20)

la-crise
la-crisela-crise
la-crise
 
Practica de word
Practica de wordPractica de word
Practica de word
 
Charte qualité-elcofrance
Charte qualité-elcofranceCharte qualité-elcofrance
Charte qualité-elcofrance
 
Estas son nuestras obras de arte
Estas son nuestras obras de arteEstas son nuestras obras de arte
Estas son nuestras obras de arte
 
Cómo usar Slideshare
Cómo usar SlideshareCómo usar Slideshare
Cómo usar Slideshare
 
Ampliación medidas cautelares Cidh
Ampliación medidas cautelares CidhAmpliación medidas cautelares Cidh
Ampliación medidas cautelares Cidh
 
Solidaridad con los desaparecidos
Solidaridad con los desaparecidosSolidaridad con los desaparecidos
Solidaridad con los desaparecidos
 
Bienvenue Au Maroc
Bienvenue Au MarocBienvenue Au Maroc
Bienvenue Au Maroc
 
post-license_min_mas1
post-license_min_mas1post-license_min_mas1
post-license_min_mas1
 
Mémoire
MémoireMémoire
Mémoire
 
Outilsdeveille
OutilsdeveilleOutilsdeveille
Outilsdeveille
 
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
Converteo - Adobe - Mesurer et personnaliser vos offres dans un contexte mult...
 
Acdc
AcdcAcdc
Acdc
 
Presentación Edad Media.
Presentación Edad Media.Presentación Edad Media.
Presentación Edad Media.
 
Fix "error de memoria tarjeta"
Fix "error de memoria tarjeta"Fix "error de memoria tarjeta"
Fix "error de memoria tarjeta"
 
Presentación Robótica
Presentación RobóticaPresentación Robótica
Presentación Robótica
 
Pronunciamiento dpe con respecto al referendum ante cc
Pronunciamiento dpe con respecto al referendum ante ccPronunciamiento dpe con respecto al referendum ante cc
Pronunciamiento dpe con respecto al referendum ante cc
 
Si tienes una idea empréndela, y verás...
Si tienes una idea empréndela, y verás...Si tienes una idea empréndela, y verás...
Si tienes una idea empréndela, y verás...
 
Presentación Video
Presentación VideoPresentación Video
Presentación Video
 
Virtualización - Evolución hacia el IT Ágil
Virtualización - Evolución hacia el IT ÁgilVirtualización - Evolución hacia el IT Ágil
Virtualización - Evolución hacia el IT Ágil
 

Similaire à Ce bon vieux propel

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -introNosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Olivier Mallassi
 
Les bonnes pratiques de l'architecture en général
Les bonnes pratiques de l'architecture en généralLes bonnes pratiques de l'architecture en général
Les bonnes pratiques de l'architecture en général
Geoffrey Bachelet
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
julien pauli
 
Php1
Php1Php1
OOP & Design Pattern - Algiers Developers Meetup August 2015
OOP & Design Pattern - Algiers Developers Meetup August 2015OOP & Design Pattern - Algiers Developers Meetup August 2015
OOP & Design Pattern - Algiers Developers Meetup August 2015
Tarik Zakaria Benmerar
 
OOP and Design Patterns
OOP and Design PatternsOOP and Design Patterns
OOP and Design Patterns
Algiers Tech Meetup
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009
Alexis Sukrieh
 
Mix it 2011 - Clojure
Mix it 2011 - ClojureMix it 2011 - Clojure
Mix it 2011 - Clojure
lolopetit
 
Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5
Mamadou Oury Ba
 
SSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQLSSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQL
Hervé Leclerc
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbc
Karim Amane
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHP
kemenaran
 
Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012
Claude Falguiere
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
Daniel Rene FOUOMENE PEWO
 
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
Tarik Zakaria Benmerar
 
Hands on lab Elasticsearch
Hands on lab ElasticsearchHands on lab Elasticsearch
Hands on lab Elasticsearch
David Pilato
 
Uniform Variable Syntax
Uniform Variable SyntaxUniform Variable Syntax
Uniform Variable Syntax
Darkmira
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
guest6e3bed
 

Similaire à Ce bon vieux propel (20)

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -introNosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
 
Les bonnes pratiques de l'architecture en général
Les bonnes pratiques de l'architecture en généralLes bonnes pratiques de l'architecture en général
Les bonnes pratiques de l'architecture en général
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
 
Php1
Php1Php1
Php1
 
OOP & Design Pattern - Algiers Developers Meetup August 2015
OOP & Design Pattern - Algiers Developers Meetup August 2015OOP & Design Pattern - Algiers Developers Meetup August 2015
OOP & Design Pattern - Algiers Developers Meetup August 2015
 
OOP and Design Patterns
OOP and Design PatternsOOP and Design Patterns
OOP and Design Patterns
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009
 
Drools
DroolsDrools
Drools
 
Mix it 2011 - Clojure
Mix it 2011 - ClojureMix it 2011 - Clojure
Mix it 2011 - Clojure
 
Spark - Ippevent 19-02-2015
Spark - Ippevent 19-02-2015Spark - Ippevent 19-02-2015
Spark - Ippevent 19-02-2015
 
Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5Améliorations dans Java depuis la version 5
Améliorations dans Java depuis la version 5
 
SSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQLSSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQL
 
Fmin103 0910 tpjdbc
Fmin103 0910 tpjdbcFmin103 0910 tpjdbc
Fmin103 0910 tpjdbc
 
Formation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHPFormation PHP avancé - Cake PHP
Formation PHP avancé - Cake PHP
 
Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012Quickie Incanter/Clojure à Devoxx France 2012
Quickie Incanter/Clojure à Devoxx France 2012
 
Introduction à JPA (Java Persistence API )
Introduction à JPA  (Java Persistence API )Introduction à JPA  (Java Persistence API )
Introduction à JPA (Java Persistence API )
 
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
Design patterns et Design Emergeant - Micro Days - Modern Software Developmen...
 
Hands on lab Elasticsearch
Hands on lab ElasticsearchHands on lab Elasticsearch
Hands on lab Elasticsearch
 
Uniform Variable Syntax
Uniform Variable SyntaxUniform Variable Syntax
Uniform Variable Syntax
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
 

Plus de Francois Zaninotto

Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !
Francois Zaninotto
 
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
Francois Zaninotto
 
La blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré luiLa blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré lui
Francois Zaninotto
 
Le jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du webLe jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du web
Francois Zaninotto
 
Frameworks : A history of violence
Frameworks : A history of violenceFrameworks : A history of violence
Frameworks : A history of violence
Francois Zaninotto
 
Php 100k
Php 100kPhp 100k
La migration continue vers Symfony
La migration continue vers SymfonyLa migration continue vers Symfony
La migration continue vers Symfony
Francois Zaninotto
 
La programmation asynchrone... et les pates
La programmation asynchrone... et les patesLa programmation asynchrone... et les pates
La programmation asynchrone... et les pates
Francois Zaninotto
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
Symfony2 meets propel 1.5
Symfony2 meets propel 1.5Symfony2 meets propel 1.5
Symfony2 meets propel 1.5
Francois Zaninotto
 
Developing for Developers
Developing for DevelopersDeveloping for Developers
Developing for Developers
Francois Zaninotto
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
Francois Zaninotto
 

Plus de Francois Zaninotto (12)

Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !Vous aimez les legos ? React est fait pour vous !
Vous aimez les legos ? React est fait pour vous !
 
GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?GraphQL, l'avenir du REST ?
GraphQL, l'avenir du REST ?
 
La blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré luiLa blockchain, quand l'individu sert au collectif... malgré lui
La blockchain, quand l'individu sert au collectif... malgré lui
 
Le jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du webLe jeu vidéo à la rescousse du web
Le jeu vidéo à la rescousse du web
 
Frameworks : A history of violence
Frameworks : A history of violenceFrameworks : A history of violence
Frameworks : A history of violence
 
Php 100k
Php 100kPhp 100k
Php 100k
 
La migration continue vers Symfony
La migration continue vers SymfonyLa migration continue vers Symfony
La migration continue vers Symfony
 
La programmation asynchrone... et les pates
La programmation asynchrone... et les patesLa programmation asynchrone... et les pates
La programmation asynchrone... et les pates
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Symfony2 meets propel 1.5
Symfony2 meets propel 1.5Symfony2 meets propel 1.5
Symfony2 meets propel 1.5
 
Developing for Developers
Developing for DevelopersDeveloping for Developers
Developing for Developers
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 

Ce bon vieux propel

  • 1. Ce bon vieux Propel RDV AFUP, 30 mars 2011 François Zaninotto
  • 2. ActiveRecord $author = new Author(); $author->setFirstName('Leo'); author book $author->setLastName('Tolstoi'); $author->save(); id id last_name * title $book = new Book(); first_name author_id $book->setTitle('War And Peace'); $book->setISBN('0143039997'); $book->setPrice(12.99); $book->setAuthor($author); $book->save(); Propel est une implémentation d’ActiveRecord Un enregistrement d’une table = Un objet On abstrait le SQL derrière la manipulation d’objets en PHP Getter et Setter pour chaque colonne, et pour les FK aussi Persistance via save() - et delete() bien sûr Propel génère les classes Author et Book à partir de la BDD - ou à partir d’un schema
  • 3. INSERT INTO `author` (`first_name`, `last_name`) VALUES ('Leo', 'Tolstoi'); INSERT INTO `book` (`title`, `ISBN`, `price`, `author_id`) VALUES ('War And Peace', '0143039997', 12.99, 123); Mais le SQL est bien là, généré par Propel. Il est toujours disponible à un clic de souris (dans un fichier de log, ou dans une propriété de l’objet de connexion). Notez que Propel gère automatiquement la clé étrangère author_id, et que les identifiants primaires n’apparaissent pas dans le code PHP. Pour la quincaillerie DBAL, c’est PDO qui est aux commandes - un PDO surboosté
  • 4. class Author extends BaseAuthor { public function getFullName() { if ($this->getFirstName() && $this->getLastName()) { return $this->getFirstName().' '.$this->getLastName(); } if ($this->getLastName()) { return $this->getLastName(); } if ($this->getFirstName()) { return $this->getFirstName(); } return 'Anonymous Coward'; } echo $author->getFullName(); // Leo Tolstoi Les classes ActiveRecord sont l’endroit idéal pour stocker de la logique métier. Cela rend les méthodes réutilisables, testables, lisibles.
  • 5. ActiveRecord est un Design Pattern http://martinfowler.com/ eaaCatalog/activeRecord.html Propel n’a rien inventé. ActiveRecord est un pattern connu depuis longtemps, et utilisé dans 80% des ORM. Ces n’est pas ça qui fait la différence entre Propel et les autres ORM
  • 6. Rapide Professionnel Ergonomique IDE friendly Il y a quatre éléments qui font vraiment la différence. Si vous ne devez retenir qu’une seule slide. 1 - Rapide: pour installer, pour exécuter, et pour apprendre les bases de Propel, il vous faudra une demi journée. 2 - Professionnel, car après plus de 7 ans d’existence et 5000 unit tests, Propel tient bon. Seul Doctrine arrive au même niveau de professionnalisme ; les autres ORMs sont loin derrière. 3 - Ergonomique, car Propel fait toujours le pari de la facilité d’utilisation. Propel prend en charge toutes les tâches évidentes, et gère sans configuration particulière les 80% des cas les plus courants. 4 - IDE Friendly, car la génération de code donne aux IDE la visibilité de toutes les méthodes, et le phpDoc a été spécialement pensée pour aider les développeurs.
  • 7. ActiveQuery Comme pour les objets ActiveRecord, Propel génère une classe de requête par table. Cela permet de proposer des raccourcis de requêtage, et d’encapsuler la logique métier dans des classes de requêtage. On a donc une véritable API objet pour requêter un entrepôt... une BDD OO?
  • 8. // trouver un objet avec sa clé primaire $author = AuthorQuery::create()->findPk(123); // conditions sur les colonnes $book = BookQuery::create() ->filterByTitle('War And Peace') ->findOne(); // raccourcis $book = BookQuery::create() ->findOneByTitle('War And Peace'); create() est une factory qui renvoie un objet déterminé, ça aide beaucoup l’IDE pour la complétion. findPk() et findOne() renvoient un objet ActiveRecord. find() renvoie une collection. filterByXXX() est la façon de dire WHERE à Propel. On peut combiner plusieurs filtres. Les classes de requêtes sont truffées de raccourcis qui facilitent la vie, comme le findOneByXXX() qui est une méthode magique... mais qui apparait dans l’IDE.
  • 9. // conditions intelligentes $author = AuthorQuery::create() ->filterByTitle('War%') ->findOne(); $book = BookQuery::create() ->filterByAuthor($author) ->find(); $books = BookQuery::create() ->filterByPrice(array('min'=>10, 'max'=>20)) ->find(); La connaissance du type de la colonne au moment de la génération des méthodes de filtre permet de leur ajouter des capacités particulières. On peut ainsi filtrer sur une chaine avec des jokers, sur une intervalle pour un nombre. Les clés étrangères sont vues comme des relations, et Propel génère des raccourcis supplémentaires. On peut ainsi filtrer sur des objets, sans connaitre les colonnes impliquées dans une clé étrangère.
  • 10. SELECT * FROM `book` WHERE `book.title` LIKE 'War%'; SELECT * FROM `book` WHERE `book.author_id` = 123; SELECT * FROM `book` WHERE `book.price` > 10 AND `book.price` < 20; Les SQL généré est toujours à un clic de souris. Le binding est fait via PDO, en fonction du type de la colonne. Vous êtes donc à l’abri des injections SQL Petit détail: le SQL montré ici est celui que Propel génère pour MySQL. Pour PostgreSQL, SQLite, SQLServer, et Oracle, Propel génère un code différent et optimisé pour chaque de base.
  • 11. class BookQuery extends BaseBookQuery { const CHEAP_LEVEL = 8; public function cheap($maxPrice = self::CHEAP_LEVEL) { $this->filterByPrice(array('max' => $maxPrice)); return $this; } } // trouver les éditions bon marché de 'War And Peace', // classées par titre $books = BookQuery::create() ->filterByTitle('War%') ->cheap() ->orderByTitle() ->find(); Les classes ActiveQuery sont l’endroit idéal pour stocker de la logique métier. Cela rend les méthodes réutilisables, testables, lisibles. On crée un DSL, un Domain-Specific Language, pour son modèle. Ca ne vous rappelle rien ? Eh oui, ce sont les mêmes principes que pour ActiveRecord.
  • 12. // trouver les auteurs ayant le prénom 'Leo' $authors = AuthorQuery::create() ->filterByFirstName('Leo') ->find(); $books = BookQuery::create() ->filterByAuthor($authors) ->find(); // la même chose, en une seule requête $books = BookQuery::create() ->useAuthorQuery() ->filterByFirstName('Leo') ->endUse() ->orderByTitle() ->find(); Queries embarquées: filterByFirstName() est une méthode de l’objet AuthorQuery. On peut l’utiliser dans l’objet BookQuery par une query embarquée, que Propel traduit par un bon vieux Join. Cela vous permet donc d’encapsuler la logique métier dans la bonne classe, et de la rendre réutilisable dans les objets liés
  • 13. SELECT * FROM `book` LEFT JOIN `author` ON `book.author_id` = `author.id` WHERE `author.first_name` = 'Leo' ORDER BY `book.title` ASC Propel connait la relation Book <-> Author, il sait donc écrire le join tout seul. En fait, toute requête SQL peut être écrite comme une suite d’appels de méthode sur un objet ActiveQuery. Mais ce n’est pas là l’essentiel: Dans Propel, on ne traduit pas du SQL en objet, on manipule directement des objets. A partir de maintenant, fini le SQL (même si vous savez qu’il est toujours derrière).
  • 14. Full Featured ActiveRecord et ActiveQuery sont la partie immergée de l’iceberg. Propel offre bien plus - voyez cette liste non exhaustive, qui montre que Hydratation combinée Propel est un ORM full-featured. Seul Doctrine 1 arrive à ce niveau. L’hydratation, c’est le fait de peupler un objet avec des données qui viennent de la base. L’hydratation transforme un objet vide (sec) en objet imbibé de données venant d’un resultset.
  • 15. Reverse engineering Hydratation Moteur combinée d’évènements Clés composites Hydratation sur Liaisons 1-1 et n-n Indexes demande Collections Vues SQL Validators Pager Autoloading Héritage de table Migrations Connections Import/Export multiples XML,YAML, JSON, Namespaces CSV Query log FK virtuelles Types Blob, Enum, Boolean, Array, Profiler Transactions Object imbriquées Introspection au Colonnes Lazy runtime Réplication master- loadées slave
  • 16. Behaviors timestampable i18n sluggable concrete_inheritance sortable aggregate_column versionable query_cache soft_delete alternative_coding_standards nested_set ... et contributions tierces Propel offre ce que tout bon ORM doit offrir, une bibliothèque de «comportements» d’objets métiers prédéveloppés, que l’on peut activer à loisir. query_cache et alternative_coding_standards ne sont pas vraiment des «comportements», mais ça montre que le système de behaviors de Propel est plus un système de plugins, qui permet de modifier le code généré à loisir
  • 17. Propel est RAPIDE 0x 2,5x 5,0x 7,5x 10,0x 12,5x PDO Scénario 1: findPk Scénario 2: hydrate Propel 1.6 Doctrine2 Doctrine 1.2 http://code.google.com/p/php-orm-benchmark/ Selon les scénarios, Propel est entre 1,5 fois et 5 fois plus lent que pdo seul. Ca peut paraître beaucoup, mais c’est à comparer au code boilerplate que vous avez pu écrire dans vos applications pour effectuer le binding des variables, tester les cas limites, chercher la bonne connexion, logguer les résultats... Etes-vous sûrs que ce code est rapide ? Propel, lui, cherche avant tout la rapidité. Et ça se voit, quand on le compare aux autres ORMs phares en PHP. Le benchmark qui permet d’arriver aux résultats ci-dessus est public, testez-le !
  • 18. Propel est PROFESSIONNEL Tests unitaires Communauté BC depuis la 1.3 Maj tous les mois Configurable Bug tracker public Documentation Utilisé par des professionnels Ecosystème (behaviors, DBDesigner, plugins) License MIT Propel a tout ce qu’il faut pour faire une application qui tient, une application qui dure, une application qui grandit. PHP n’est pas forcément le langage dans lequel on trouve le plus de librairies professionnelles. Propel en est une. Il a été choisi par de nombreuses sociétés parce qu’il est professionnel. Chaque patch contient des tests et de la doc - c’est du DDD, documentation-driven development (cherchez le terme pour rire un peu). La doc, c’est mon dada - j’ai déjà écrit deux bouquins. Propel, c’est sept ans d’efforts.
  • 19. Propel est ERGONOMIQUE $book->setCreatedAt(time()); $book->setCreatedAt('now'); $book->setCreatedAt('2011-03-30 20:15'); $book->setCreatedAt(new DateTime()); C’est à Propel de s’adapter à vous, pas à vous de vous adapter à Propel. Zéro configuration pour commencer. Une seule dépendance externe: Phing. Mais si vous utilisez symfony ou Symfony2, le setup est instantané et Phing est livré avec. Peu d’objets à manipuler (ActiveRecord, ActiveQuery, connection), d’où un apprentissage très rapide. Pas de magie: le code est généré et accessible. phpDoc complète.
  • 20. Propel est IDE FRIEDNLY Les IDE avec autocomplétion tirent parti des information générées par Propel au format phpDoc pour faciliter encore davantage la vide des développeurs.
  • 21. ActiveRecord Not Dead DataMapper ActiveRecord N’écoutez pas ceux qui vous disent qu’ActiveRecord est mauvais. C’est juste une histoire de goût. ActiveRecord permet de tester son modèle. La preuve: Propel a plus de 5000 tests. L’héritage n’est pas un problème puisque les behaviors permettent la réutilisation horizontale. Quant à la performance, ça n’a jamais été un problème que pour les ActiveRecord n’utilisant pas de génération de code. Pour comparer, EntityManager, c’est le goût de la pureté de Java. ActiveRecord, c’est le goût de la facilité de Ruby et Rails. Les deux viennent de Fowler.
  • 22. Merci François Zaninotto, lead dev Propel Site: http://www.propelorm.org Blog: http://propel.posterous.com Twitter: @francoisz eTF1 recrute, contactez-moi !