Ant

Bien connu des développeurs Java, Ant est un build-system, à l’instar des Makefiles, permettant d’automatiser le déploiement d’un projet. Bon nombre de projets PHP ne sont en effet pas directement utilisables tout de suite après récupération des sources, et/ou nécessitent un certain nombre d’adaptation en fonction du serveur sur lequel le projet est déployé. Voire même, parfois, certaines tâches de maintenances assez rébarbatives pourraient être automatisées.

Je ne connais même pas Ant !

Pour ceux qui ne connaissent pas du tout Ant (et je ne parle pas d’un diminutif d’Antoine…), les rouages tournent concrètement grâce à un fichier XML classiquement nommé « build.xml », comprenant une succession de balises du style :

<target name="NOM_REGLE" depends="REGLES À EFFECTUER AUPARAVANT">
     <actions à effectuer ... />
</target>

Une fois ce fichier XML dûment rempli, vos règles s’exécutent par le biais d’une ligne de commande, après bien entendu avoir vérifié qu’Ant était bien installé sur votre machine :
> ant NOM_REGLE

Il y a un certain nombre d’options disponibles, il est par exemple possible d’afficher les règles disponibles et leur rôle respectif via ant -p pour peu que vous ayez renseigné un champ « description » dans le fichier build.xml.

Bon, et pour mon projet, ça sert à quoi ?

Vous manquez d’imagination ? Voici à titre d’exemple la liste de règles que j’ai définie pour Piwam :

  • init: Créer les répertoires manquants (log, cache, build…
  • cc: Vider le cache
  • doc: Générer la documentation Doxygen
  • up: Update SVN
  • phpcpd: Cherche le code PHP dupliqué au sein du projet
  • pdepend: Génère un rapport de dépendance des classes
  • phpcs: Vérifie la conformité du code avec une norme donnée
  • lint: Vérifie qu’aucun fichier ne contient une erreur de syntaxe
  • test: Lance les tests unitaires et fonctionnels
  • css: Concatène l’ensemble des fichiers CSS en un seul grand fichier CSS
  • css.min: Minimise la taille du gros fichier CSS. (appelle automatiquement la règle css en amont)
  • clear: Nettoie les fichiers générés
  • build: Lance l’ensemble des tâches permettant de vérifier la qualité du projet

je vous invite à découvrir le fichier XML correspondant sur le dépôt SVN du projet. Ce fichier vous permet alors d’effectuer toute une batterie d’actions de manière extrêmement simplifiée. Ant est utilisé au sein d’une multitude d’outils du monde Java, des IDE (Eclipse…) aux outils d’intégration (Hudson, CruiseControl…). En pratique, ces outils vont aller lire votre fichier build.xml et appeler les commandes correspondant aux tests (dans mon cas : phpcs, pdepend, etc.) de manière 100% automatisée afin de vous permettre de suivre l’évolution de votre projet au fil des révisions.
Sur ce, je vous laisse rédiger votre propre antfile, en attendant de vous présenter comment l’exploiter au sein d’Hudson dans un projet article !

Liens utiles

hiphop

Certains d’entre vous ont peut être entendu parler d’ »Hyper PHP ». Le nom du projet est apparemment « HipHop ». Il s’agit là du compilateur complètement customisé par Facebook, pour ses propres besoins liés à la scalabilité et la montée en charge.

Ce compilateur réécrit le code PHP en C++, puis le  compile avec le bien connu compilateur G++. Chez Facebook, ils nous font part d’un gain de 50% en terme d’utilisation du CPU.

hiphop2Utilisé en production depuis 2 ans mais présenté seulement aujourd’hui à la communauté, le projet HipHop est d’ores et déjà disponible, n’hésitez pas à l’essayer

correction

Vous avez récemment découvert mon histoire d’un curieux recrutement. J’y montrais alors une portion de code PHP exemptée de bonne pratique et fourmillant d’erreurs. This might sound more complicated than playing online casino (http://www.casino.com/fr/) at first but you will soon get your head around it. Voici donc la « correction » que je vous propose, recensant les points que j’aurais aimé voir soulevés par les candidats :

  1. Le tag <?php dans sa version courte
  2. Un code intégralement en français.
  3. Pas de commentaires multi-lignes en entête de fonction
  4. Pas de tags pour la génération de documentation (phpDoc, Doxygen…)
  5. Pas de typage pour le paramètre $voiture (en tant qu’objet, autant bénéficier du typage apporté par PHP)
  6. Commentaires inutiles dans le code (lignes 8 et 13)
  7. Mauvaise indentation
  8. Problème de type pour $max
  9. If/else à problème
  10. L’opérateur de comparaison pourrait être poussé à « ===« 
  11. Lorsque que $max vaut « inconnu », on pourrait préférer une constante
  12. Pas d’utilisation d’ORM, utilisation de mysql_query natif
  13. Requête SQL peu lisible (mots clés en minuscules, une seule ligne…)
  14. Problèmes dans la requête SQL (guillemets mal placés, le SET est après le WHERE)
  15. Pas de protection de la requête
  16. return est un mot clé, pas une fonction : on devrait omettre les parenthèses.
  17. Il vaut mieux éviter d’insérer les tags de fermeture PHP
  18. Vu ce que fait la fonction, ça serait sûrement mieux d’en faire une méthode au sein de la classe (mais l’analyse de ce que fait la fonction n’était pas demandé)

Bravo à tous ceux qui avaient farfouillé ! Sans forcément trouver exactement tous ces points, il était sûrement aisé d’en identifier au moins 4 ou 5. Attention, ce ne sont pas forcément des erreurs, mais des points qui pourraient être discutés (les commentaires pourraient très bien être en français pour telle ou telle raison, par exemple)

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 :

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.

PhpTV

Ne nous arrêtons pas en si bon chemin, et diffusons, rediffusons les slides utilisés comme support lors des conférences :

Et en bonus, PHP TV vient de publier les conférences sous forme de fichiers audio, à découvrir dès maintenant.

Vous l’avez peut être remarqué en regardant les photos, des écrans diffusaient en live les tweets envoyés avec le hashtag #afup. Tout le long de l’évènement, la bonne humeur s’enchaînait avec humour sur la plateforme de micro-blogging. Je vous offre ici un best-of de ce qui s’est raconté, prenez donc 2 minutes !

  • « That’s not what you wanted to hear, but that’s what I wanted to say! » (Monty, en parlant du business model pour MariaDB)
  • « Il faudrait un ring dans la salle : monty vs (sun + Oracle) » (Monty est fondateur de MySQL AB, qu’il a quitté suite au récent rachat)
  • « mysql -> mariadb, ? il faut juste apprendre à claquer des doigts »
  • « Pour info, erreur 404 sur m6web.fr » (pendant la conf d’M6web)
  • « PHP 4 pour les sites jetables codé par des stagiaires // Pas faux! »
  • « Le singleton nuit gravement à la santé de votre code » (Fabien Potencier, pendant la conférence sur PHP 5.3)
  • « Le ZendFramework a plein de Singletons // BIM! (bon ok je troll, pardon) » (Fabien Potencier)
  • « Encouragez les employés à aller boire » (conférence Motiver ses développeurs)
  • « L’absence de système de contrôle de révisions peut faire partir un développeur » (la même conférence)
  • « Shooter son patron au paintball ça fait du bien » (encore la même !)
  • « Motiver ses développeurs » : on vante l’importance des gadgets (Nerf, jeux vidéos…). Taser? :)  »
  • « Pinba ? c’est pas le pote de Timon dans le Roi Lion…. Désolé je sors ! »
  • « « Apache n’est pas un indien hein, on ne va pas parler de celui-là »

Avant même quelques impressions (et bien + encore) voici un – petit – reportage photo de cette édition 2009 du forum PHP, ces 12 et 13 novembre à la Cité des Sciences (Paris).

Le hall

Le hall

Conférence MariaDB par Michael Widenius

Conférence MariaDB par Michael Widenius

La scéance Black Vodka / Questions après la conférence sur MariaDB

La séance Black Vodka / Questions après la conférence sur MariaDB

La diffusion Twitter de #afup en live dans le hall

La diffusion Twitter de #afup en live dans le hall

Le concours eeePC organisé

Le concours eeePC organisé

La salle des projets PHP

La salle des projets PHP

Conférence PHP5.3 par Fabien Potencier

Conférence PHP5.3 par Fabien Potencier

Le stand symfony

Le stand Sensio Labs

L'amphi vu du sol

L'amphi vu du sol

Avis, réactions, rapports et compagnie à venir dans de prochains billets !

C’est officiel, j’aurai l’honneur de présenter Piwam à l’édition 2009 du forum PHP, les 12 et 13 novembre à la Cité des Sciences (Paris). aux côtés entre autre de FineFS, Hoa et WampServer.

Si vous souhaitez assister aux conférences de ce forum professionnel, vous pouvez bénéficier d’un tarif préférentiel (140 euros les 2 journées, au lieu de 180) en inscrivant le code « PIWAM ».