Symfony Color Scheme

NetBeans 6.8 vient de sortir en version stable comme l’annonçait précédemment un sympathique lecteur / commentateur (rev). Pour fêter cela, je viens de passer une petite heure à créer un thème aux couleurs utilisées par Sensio Labs pour les snippets made in symfony (exemple). J’ai adapté les couleurs pour le code PHP, HTML, YAML, SQL, JavaScript et XML.

Télécharger maintenant !

NetBeans 6.8 RC2

Pourquoi ?

Pourquoi donc me suis-je mis à délaisser Eclipse au profit de NetBeans ? Ma motivation remonte à l’annonce d’un début d’intégration de symfony au sein de l’IDE, c’est à dire il n’y a pas trop longtemps. J’avais eu l’occasion de tester NetBeans il y a 3 ou 4 ans, pour le comparer à Eclipse qui me semblait alors plus puissant, notamment pour certains plugins que j’utilisais.

Aujourd’hui, dans un projet qui contient de très nombreux fichiers (symfony) NetBeans se montre subjectivement plus rapide pour autocompléter et documenter les appels de méthodes. Je regrette le non-support des interfaces fluent sur plusieurs lignes, mais bon… Au niveau de l’intégration du framework, je ne sais pas encore si j’arriverai à abandonner mon terminal et son ZSH, mais il y a du mieux au sein de l’IDE :

Symfony via le menu contextuel

Symfony via le menu contextuel

Fenêtre d'exécution de commandes symfony

Autre résultat de cette intégration fort intéressant, la possibilité de switcher entre une vue et son contrôleur :

Passer d'un contrôleur à la vue associée

Passer d'un contrôleur à la vue associée

Pour ne pas dérouter les utilisateurs d’Eclipse, un mapping du clavier de l’IDE rival est disponible ; on notera également un mapping Emacs redoutable ! Par défaut, les raccourcis claviers sous MacOSX sont désastreux, avec des inversions entre les touches SHIFT, CTRL et Pomme. Fort heureusement NetBeans propose une configuration extrêmement poussée du clavier, je vous laisse découvrir les différentes assignations possibles. Enfin, petit agrément appréciable au quotidien que je découvre avec NetBeans, l’affichage dans la marge des modifications effectuées depuis la dernière version. Un exemple visuel :

Une marge qui fait la diff' !

Une marge qui fait la diff' !

En passant le curseur sur cette marge, l’IDE nous indique les modifications effectuées. L’équivalent sous Eclipse est amplement moins pratique,

Le mot de la fin

Je n’ai sûrement pas encore fait le tour des avantages (et des inconvénients) de NetBeans, et voilà un bon prétexte pour continuer à pousser son utilisation plus loin. La première semaine d’utilisation me donne pleinement satisfaction après un petit moment passé dans les préférences pour personnaliser la coloration syntaxique, les raccourcis claviers et le formatage automatique.

Piwam.org

Il était temps. Jusqu’alors, les news étaient affichées sur l’espace Google Code, et relayées sur le présent blog. En somme, rien de bien pratique pour un non-développeur qui n’a que faire des détails d’implémentation, et qui se contre fiche du choix Propel vs Doctrine.

Afin de maximiser les bonnes relations entre le projet et ses utilisateurs, j’ai décidé de créer Piwam.org, nouvelle plate-forme officielle diffusant l’actualité du projet, ses évolutions, en interaction avec les utilisateurs par le biais de sondages. Du coup, ZT ne relaiera plus les sorties mineures ni les décisions en temps réel. En revanche, les articles et réflexions techniques continueront d’avoir leur place ici. Quant à piwam.org, bien évidemment, c’est tout le contraire ! Bref, à découvrir sur www.piwam.org.

Encore un framework

Vous étiez prévenu, le forum PHP 2009 fût une excellente occasion de découvrir un certain nombre de projets, apportant chacun leur lot d’innovations. Suite à la première conférence à laquelle j’ai pu assister, « Optimiser PHP avec un préprocesseur« , Nicolas Grekas a présenté – et tenté d’évangéliser – son framework fait maison : Patchwork.

Développé en interne, Patchwork est né comme souvent pour résoudre certaines problématiques. Ici, c’est la portabilité et la « cohérence » des applications qui intéressent son auteur.

Portabilité ?

L’objectif est ici de faciliter le déploiement des applications PHP en fonction du serveur de destination. Une fonction pas disponible ? Une autre qui a un comportement différent selon la version ? À l’instar des autotools de l’univers C/C++, Patchwork permet de se prémunir contre ce genre de situations. Concrètement, voici la manière de spécialiser un appel en fonction du contexte :

/**/if (! function_exists('utf8_decode'))
/**/{
      function utf8_decode($string)
      {
          // ...
      }
/**/}

Cohérence ?

Le mot est peut être mal choisi, mais l’idée est là. L’idée est d’homogénéiser le code en appliquant un certain nombre de règles :

  • Le même encodage (UTF-8) partout
  • CRLF vs CR vs LF
  • ‘@’ (opérateur de silence) ou non ?
  • Fonctions à substituer…

Le dernier point s’avère utile dans bien des cas : utiliser une fonction plus optimisée, rajouter des fonctionnalités… Quelques exemples concrets de substitutions ?

rand => mt_rand
md5  => hash('md5', ...)

Le préprocesseur de Patchwork se charge également de booster le mécanisme d’autoload de PHP5, et bien entendu place tous les résultats de compilation en cache afin de ne pas tout recalculer à chaque appel ; d’où le nom de pré-processeur. Les benchmarks effectués laissent apparaître un gain de performances de l’ordre de 5%.

Mon avis

Patchwork part d’un très bon sentiment et d’une problématique qui existe au sein de nombreux projets. C’est un projet jeune, déjà utilisé en production, et documenté (en français). Patchwork est une opportunité de s’amuser avec toutes les possibilités offertes par PHP5, et peut aisément servir pour « maintenir » une application vieillissante, ou sur laquelle on a peu de contrôle. En revanche, certains points pourraient être un non-sens dans bien des cas. Ainsi, la substitution de fonctions par leurs cousines plus performantes pourrait ne plus avoir de sens dès lors que l’équipe de développement intègre directement ces best-practices.

Liens :

fk_breaker

Aux débuts de Piwam, les relations décrites dans le fichier schema.yml n’étaient pas nommées explicitement. Du coup, lors de la génération du schmilblick par Propel (Model + SQL), c’est InnoDB qui s’occupait de trouver un nom à ces relations.

Aujourd’hui, j’écris le script permettant de migrer de Piwam 1.1.2 vers Piwam 1.2, script qui nécessite d’effectuer des opérations sur des foreign keys, en l’occurence les supprimer… Comment diable alors faire référence à une clé étrangère dont on ne connait pas le nom ? Après avoir farfouillé partout sur la toile, il apparaît qu’il n’y a pas moult solutions pour arriver à mes fins. On se retrouve ainsi soit à écrire des procédures, soit à faire appel à l’information_schema. Enfin, certains proposent une utilisation de SHOW TABLE avec les arguments qui vont bien, puis parser la sortie pour récupérer les noms des contraintes. J’ai pu par ailleurs découvrir la version Firebird :

SELECT RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS
WHERE RDB$CONSTRAINT_NAME LIKE 'FK%' AND
RDB$RELATION_NAME='MATABLEAMOI'
ORDER BY RDB$CONSTRAINT_NAME

Ne pouvant exécuter de requêtes propres à Firebird, ni même de procédures (Piwam tourne sous trop de types de serveurs différents aux configurations et autorisations bien différentes), j’ai finalement opté pour une solution ma foi fort simple. Accrochez-vous, c’est du SQL de très haut niveau (hum…).

CREATE TABLE ma_table_copy AS SELECT * FROM ma_table;

Une copie réalisée de la sorte a pour effet de ne copier que la structure et la table, en omettant indexes et contraintes. Lent, mais portable (je ne sais pas si l’adjectif est vraiment adapté) et pratique. Tout ça pour dire, bordel, une bonne fois pour toutes, n’oubliez pas de nommer vos contraintes explicitement, ça facilite grandement la maintenance !

Pirum Header

L’acronyme pourrait laisser entendre qu’il s’agit d’un petit frère de Piwam. Pirum, est un gestionnaire de serveur de canaux PEAR réalisé par Fabien Potencier (Sensio Labs). Il y a encore quelques limitations (pas de catégories, pas d’interface web pour gérer les packages…) mais c’est tout de même largement utilisable et… utilisé ! Swift Mailer, Twig, PHPUnit, symfony et Pirum lui même utilisent cette solution. http://www.pirum-project.org

Doctrine

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.

Flickriver

Ça faisait un moment n’est-ce pas ? Il faut dire que ces derniers temps, j’ai surtout découvert des projets géniaux, ou des articles géniaux, mais cela ne suffit pas pour prétendre au « lien de la semaine ». C’est pour cette raison que la série devrait être prochainement complétée par ses frères et soeurs « projet de la semaine » et « article de la semaine« .

Mais cette semaine, c’est bel un bien un lien, Flickriver, qui se trouve en haut de l’affiche. Basé sur l’API offerte par Flickr, cette rivière de photos vous permet de découvrir les clichés réputés « intéressants » du moment, dans un fil potentiellement infini d’images de qualités qui déroulent sous vos yeux. Le genre de lien que je vais consulter au moins une fois par semaine quand je suis en panne d’inspiration, pour voyager ou simplement imaginer. http://www.flickriver.com

J’ai récemment migré Piwam vers symfony 1.4. Une tâche ma foi fort peu consommatrice de temps et qui se fait plutôt sans encombre, du moins pour un projet tel que Piwam, recodé from scratch avec symfony 1.2 .

En revanche, pour de gros projets débutés parfois sous symfony 1.0, qui ont effectué une mise à jour vers 1.1, puis 1.2, il va falloir s’assurer que TOUT a bien été mis en place pour éviter que la migration tourne au désastre. Symfony 1.3 assure en effet la rétro-compatibilité, mais la mouture 1.4 ne pardonne pas (clone de la 1.3, mais les éléments deprecated sont supprimés).

C’est alors là que le billet devient intéressant, puisque je vous annonce que Fabien Potencier a eu l’idée de mettre en place une tâche « project:validate« , qui effectue une multitude de vérifications pour que tout se passe en douceur. À essayer avec la dernière version !

Google Wave Coule

C’est la question que je me pose lorsque je vois le nombre de blogs capables d’organiser des concours pour gagner une invitation au service. On en arrive à un point que tout bonhomme possédant des invitations ressent l’envie de crier au monde entier qu’il organise un concours.

On peut comprendre un tel engouement à la première semaine de lancement, mais là franchement, il y a plus d’offres que de demandes. Doit-on en conclure que Wave est en passe de devenir le futur G-Flop ?