
Piwam est historiquement basé sur Propel. Parce qu’il est né avec symfony 1.0, et qu’à ce moment là, il « fallait » apprendre Propel, très en vogue.Mais la donne a changé, Doctrine est devenu l’ORM par défaut dans symfony, l’avenir du projet est bien plus certain que celui de Propel. J’ai donc décidé de changer d’ORM pour Piwam, et j’ai décidé de vous faire part de cette excitante expérience.
Les gros changements
Au premier abord, la logique de Doctrine déroute. La sélection des enregistrements se fait avec une approche de « méta-langage », le DQL, à l’instar de ce qui se fait dans Hibernate (pour les Javatistes) et le HQL. Adepte de l’approche 100% objet, j’y trouvais là un premier reproche par rapport à un Propel clair et loin de tout langage SQL. Ainsi pour sélectionner une liste d’utilisateurs qui sont dans le groupe « 42″, on procèdera de la sorte :
class UserTable extends Doctrine_Table
{
/**
* Retrieve users who belong to the group $id
*
* @param integer $id
* @return array of User
*/
public static function getForGroupId($id)
{
$q = Doctrine_Query::create()
->from('Member m')
->where('m.group_id = ?', $id);
return $q->execute();
}
}
Finalement, cette manière de faire rappelle les habitudes prises en HQL et s’avèrent agréables à utiliser en PHP. On notera par ailleurs que la table hérite tout de suite de Doctrine_Table ; nous n’avons plus accès aux méthodes statiques auto-générées par Propel (doSelect(), doCount()…). À vous de les ré-implémenter !
À l’instar de Propel, Doctrine propose de méthode pour hydrater les résultats : sous forme d’objets ou sous forme de tableaux. Remplacez alors l’appel à ->execute() par ->fetchArray(). Un benchmark réalisé sur AmicalementWeb présente des gains de performances non négligeables pour la seconde méthode. Dans le cadre de Piwam, je suis néanmoins resté sur ma gestion d’objets, pour éviter d’avoir à réécrire les templates, et parce que les performances sous Piwam ne sont pas un point critique.
Les trucs cools de Doctrine
On s’aperçoit très vite qu’il y a plein de choses super cools dans Doctrine. Je veux parler par exemple de l’export / import ultra-facilité dans différents formats (XML, YML, Json), des post- et pré- méthodes, ou encore un comportement géographique ! La possibilité d’ajouter des plugins nous confortent encore plus quant au choix d’avoir abandonné Propel ! L’intégration à symfony est elle aussi bien poussée, à tel point qu’il est possible d’exécuter des requêtes DQL directement depuis la ligne de commande via la tâche doctrine:dql.
Ma méthodologie
Plutôt que de « bidouiller » le fichier schema.yml de Propel, j’ai décidé de laisser Doctrine générer un nouveau schema.yml à partir de la structure actuelle de la base de donnée.
> php symfony doctrine:build-schema
Après avoir renommé les noms des relations et supprimé les relations à double sens qui alourdissaient inutilement la lecture et créaient une trop forte dépendance entre les classes, en avant pour la génération des fichiers Model. Tout comme pour Propel, on dispose de tâches puissantes et explicites, avec la possibilité (youpi !) de regénérer uniquement certaines classes du modèle.
Vous remarquerez que le nom des classes générées a changé. Du moins, l’équivalent des classes « Peer » de Propel, maintenant suffixées par « Table » comme dans mon exemple. Vous pouvez envisager une session de chercher/remplacer automatisée dans votre liste de contrôleurs, c’est ce que j’ai fais et c’est plutôt rapide et efficace. J’ai opté pour ce choix afin de rester dans la « logique » Doctrine. L’autre solution ? Renommer ces classes avec les anciens noms donnés par Propel.
Si votre application comporte très majoritairement des requêtes basiques de sélection / insertion / mise à jour, la ré-écriture des méthodes est relativement rapide. MAIS, c’est relativement énervant de se voir refaire un travail déjà effectué, et assez peu automatisable, en créant de surcroît un nouveau risque d’erreur.
Note d’auteur
Je ne sais pas si c’est un fait ou un hasard, mais en cherchant de la documentation sur Doctrine, je suis tombé sur pléthore de sites montrant des exemples de requêtes intégrés… dans leur contrôleur. Je ne me souviens pas avoir vu autant d’horreurs en faisant des recherches Propeliennes !
Le soucis des formulaires
Ne prenez pas peur, c’est un tout petit soucis. Et oui, pour peu que vos formulaires intègrent de la logique « Propel » (vérification d’unicité, listes de sélections générés via des Criteria, etc.) vous allez devoir mettre à jour chacun de ces formulaires. C’est en qui me concerne la partie que je considère comme la plus énervante.
Mon avis
Pour conclure sur ce bref retour, qui s’est fait dans un cadre propre à un et un seul projet (Piwam), je dirais que switcher de Propel vers Doctrine n’est pas anodin mais peut s’opérer sans douleur. Avoir des tests en place permet de s’assurer du fonctionnement une fois la procédure achevée. Je recommanderais à ceux qui veulent opérer de la sorte sur un projet conséquent de procéder par itérations, et d’intégrer chaque classe Propel les unes après les autres, quitte à se retrouver avec un mélange improbable de classes. Bien avant cela, je pense que la migration vers Doctrine est loin d’être systématique et que Propel n’est pas mort. Comprenez par là que si votre estimation du temps nécessaire pour migrer est bien supérieur à votre temps disponible, n’hésitez même pas et restez Propeliste. Au pire, commencez une nouvelle branche de votre projet avec Doctrine.