Category Archives: Work

PHP, Reflection et Annotations

J’ai récemment eu à coder à mon taf des jeux de tests pour valider le comportement de mon serveur de pub, et pour ça, j’ai codé des petits scripts tout bête pour créer/modifier les données dans une base postgresql. J’aurai pu prendre un ORM tout fait (propel, doctrine…), mais j’ai juste codé mes classes tout bêtement et le plus simplement du monde. Un exemple:

class Voiture
{
    public $id;
    public $marque;
    public $couleur;
};

Pour les requêtes d’insert, au lieu d’avoir des méthodes spécialisées dans chaque classe, j’ai codé juste une fonction save() qui prend l’objet à sauver, et qui parse grâce aux fonctions get_class_* ses propriétés pour générer les requêtes d’INSERT ou d’UPDATE. Cette fonction ressembait dans un premier temps à:

function save($obj)
{
    $class_name = get_class($obj);
    $class_vars = get_class_vars($class_name);

    $fields_names = '';
    $fields_values = '';

    $fields_count = 0;

    foreach($class_vars as $var_name => $var_value)
    {
        if(isset($obj->$var_name))
        {
            $fields_names .= $var_name . ', ';
            if(is_string($obj->$var_name))
                $fields_values .= '\'' . $obj->$var_name . '\', ';
            else
                $fields_values .= $obj->$var_name . ', ';

            $fields_count ++;
        }
    }

    if(0 == $fields_count)
    {
        return -1;
    }

    // Remove trailing ', ';
    $fields_names = substr($fields_names, 0, strlen($fields_names) - 2);
    $fields_values = substr($fields_values, 0, strlen($fields_values) - 2);

    return "INSERT INTO " . $class_name . "(" . $fields_names . ") VALUES (" . $fields_values . ");";
}

Ca me contentait dans pas mal de cas simples, mais très rapidement, cela à montré ses limites. J’avais besoin de connaître plus précisement les types des champs dans la base. Et la solution a été d’utiliser les annotations, pour ne pas avoir de longues et lourdes modifications à faire dans toutes mes classes d’objet. PHP ne propose pas out of the box un système complet d’annotation, mais incorpore les outils pour développer un comportement analogue: les classes Reflection.

Ces classes permettent de faire du « reverse engineering » sur les classes, les interfaces etc pour retrouver les différentes composantes de ces objets, qu’ils soient instanciés ou non. Et de plus, elles permettent de récupérer les commentaires des classes, des méthodes et des propriétés s’ils existent. Il n’y a qu’à les mettre en application:

<?php

/**
 * Commentaire classe voiture
 */

class Voiture
{
    /**
     * Commentaire propriete id
     */

    public $id;
}

$voiture = new Voiture;

$reflection = new ReflectionClass($voiture);
echo "Classe:\n";
echo $reflection->getDocComment() . "\n";

foreach($reflection->getProperties() as $property)
{
    echo $property->name . ":\n";
    echo $property->getDocComment() . "\n";
}

Ce qui donne:

$ php test_2.php
/**
 * Commentaire classe voiture
 */
id:
/**
     * Commentaire propriete id
     */
$

Il ne resterait plus maintenant qu’à définir ses keywords, parser les commentaires propement pis à coder son propre mini-orm sans modifier les objets finaux.

Et voilà un début:

<?php

class DbObject
{
    public function save()
    {
        $schema = $this->buildSchema($this);
        /* Ici y a du code */

        return TRUE;
    }

    private function buildSchema()
    {
        $class_name = get_class($this);
        $class_vars = get_class_vars($class_name);

        $class_reflection = new ReflectionClass($this);
        echo $class_reflection->getDocComment();

        $schema = array();

        foreach($class_vars as $var_name => $var_value)
        {
            $prop_reflection = $class_reflection->getProperty($var_name);
            $comment = $prop_reflection->getDocComment();

            $comment = preg_replace(',\/\*\*(.*)\*\/,', '$1', $comment);
            $comments = preg_split(',\n,', $comment);

            $key = $val = NULL;
            $schema[$var_name] = array();

            foreach($comments as $comment_line)
            {
                if(preg_match(',@(.*?): (.*),i', $comment_line, $matches))
                {
                    $key = $matches[1];
                    $val = $matches[2];

                    $schema[$var_name][trim($key)] = trim($val);
                }
            }
        }
        var_dump($schema);

        return $schema;
    }
};

class Voiture extends DbObject
{
    /**-
     * @DbType: integer
     * @DbValue: 0
     */

    public $id;

    /** @DbType: string
     *
     * Blabla.
     *
     */

    public $marque;

    /** @DbType: string */
    public $couleur;
};

$voiture = new Voiture;
$voiture->id = 1;
$voiture->marque = 'renault';
$voiture->couleur = 'bleu';
$voiture->save();

buildSchema retournera dans cet exemple:

$ php test_annotations.php
array(3) {
  ["id"]=>
  array(2) {
    ["DbType"]=>
    string(7) "integer"
    ["DbValue"]=>
    string(1) "0"
  }
  ["marque"]=>
  array(1) {
    ["DbType"]=>
    string(6) "string"
  }
  ["couleur"]=>
  array(1) {
    ["DbType"]=>
    string(6) "string"
  }
}

Pour finir, quelques petites références sur le sujet:

Et au final, au lieu de réinventer une roue bien vieille, je suis parti utiliser Addendum:

Firebug & xpath

Pour mon nouveau job, j’ai mis en place Selenium pour les tests fonctionnels sur le projet, et rapidement j’ai eu le besoin de tester une expression xpath pour l’un de mes tests, et je n’avais pas envie d’installer une application tierce rien que pour ça.

Après une rapide recherche, il suffit simplement d’utiliser la fonction $x(« … expression xpath… ») dans la console de firebug pour tester rapidement la validité d’une expression, et son résultat.

Plus de fonctions de la console firebug sont documentés sur cette page.

Et ça repart.

Suite à mon précédent appel pour un nouveau travail, j’ai décidé d’accepter une opportunité dans une petite agence et de prendre la tête d’une équipe de développement complète pour coder from scratch un nouveau serveur de pub, pouvant délivrer 5 milliards de pubs/mois (avec des pics à 5000/sec), avec une belle et complète interface pour les stats en temps réel et un vrai moteur décisionnel pour mieux répondre aux besoins des clients: beaucoup d’heures au bureau en perspective !

Cette phase de recherche d’emploi a été beaucoup plus rapide que prévue, et m’a un peu déstabilisé par le grand nombre de contact: plus de 180 mails de solicitation reçus dans un interval d’un mois et demi. Désolé pour tous ceux qui n’ont pas eu de réponse de ma part, c’était gentil d’essayer. ;-) Si j’ai quelques conseils pour la majeure partie d’entre vous, ils seraient:

  • Ne demandez pas de vous envoyez un CV. Il est déjà présent et téléchargeable là où vous avez eu les informations de contact;
  • Ne demandez pas à vous recontacter pour présenter quoi que ce soit: décrivez l(es) offre(s) dans le mail;
  • Mails à minima personnel un « Cher Monsieur MARIE » primant sur le c/p direct de l’offre;
  • Ne dites pas que vous avez laissé un message sur le téléphone portable. Surtout quand je n’ai pas de message sur la dite boite vocale car vous n’avez pas mon numéro;
  • Chiffrez les émoluments. Ne dites pas que c’est en fonction des compétences. Si vous nous contactez c’est que vous avez lu le CV, donc que vous pouvez nous donner cette infromation, quitte à renégocier par derrière;
  • Ne mettez pas en doute par mail les compétences. Il y a des menteurs, mais il y a aussi des gens honnêtes. Et il n’y a rien de plus pénibles de lire lors d’un 1er échange que le salaire demandé n’est peut être pas en adéquation avec les « fameuses compétences ». Testez-les en cas de doute, mais ne les mettez pas en doute.
  • Merci aux entreprises me disant qu’il était obligatoire d’être présent dans leurs locaux à 9h sur Paris. Je comprenne que cela soit nécessaire pour les ouvriers dans une usine mais quel est le but de l’imposer à des développeurs qui arriveront énervés à cause du métro bondé et creuvés car ils auront voulu coder un truc jusqu’à 1h du mat’. Perso, c’était la 1ère chose que je demandais: avoir une flexibilité totale sur les horaires, ne voulant être jugé que sur les résultats et pas sur ma capacité à régler un réveil pour faire 9-18.

A bon entendeur, à plus tard !

Mise à jour le 25/03: J’ai quitté l’entreprise que j’avais rejoins début Février. J’ai retrouvé un autre boulot pour faire plus ou moins la même chose, mais dans un groupe un peu plus sérieux.

A la recherche d’une nouvelle aventure

Pour les gens pressés: Je suis lead-developer et je suis à la recherche d’un nouveau job sur Paris dans les technos Web. Téléchargez dès maintenant mon CV.

Pour les autres, un peu d’explication:

Presque deux ans après mon arrivée sur Paris pour travailler dans une entreprise proposant une solution de text-mining innovante, où j’ai accompli je pense avec succès les missions diverses et variées que l’on m’avait assignées et plus encore, j’ai décidé de partir à la recherche d’une nouvelle aventure, m’étant beaucoup investi et les divergences d’opinions étant devenues difficiles à porter.

Ne nous trompons pas: Ces deux années ont été très riches techniquement dans cette société qui édite des solutions initialement destinées à la modération de chats. Etant une véritable force de proposition, j’ai permis aux outils de l’entreprise d’être exploitables dans de nouveaux contextes (nous sommes passés du simple chat à la possibilité technique de modérer les flux SMS de pays entiers, gérant plusieurs centaines de milliers de messages / seconde), avec des nouvelles techniques permettant de détecter avec plus de précision et de sens les altérations des mots grâce à des patterns complexes, et à destination d’un nombre plus large de client (grace au développement de bibliothèques compatibles en C, C++, C#, Java, Python, Ruby…).

Ma flexibilité technique, mon ouverture d’esprit et ma motivation ont également permises à l’entreprise de conquérir de nouveaux marchés, comme celui des outils facilitant la modération et le community management grâce à une application web, que j’ai conçu, développé et maintenu seul jusqu’à ce jour, à destination des administrateurs des business/fan pages sur Facebook. Au passage, de ce fait j’ai une très bonne connaissance grâce à ce produit des APIs facebook (fbml, fbjs, graph, old-rest, javascript…), Twitter et encore Amazon ECommerce… le tout en autodidacte.

Je suis donc à la recherche d’une nouvelle aventure, de préférence dans une jeune petite ou moyenne structure avec un véritable projet cohérent et promettant de belles perspectives. Exit les SSII où je ne vois aucune évolution possible, les grands groupes où l’on impose de faire 9h-18h (c’est sans appel).

Dans quel domaine ? Si possible dans le web ou proche. Je privilégierai là où il existe un véritable challenge technique, où je pourrai porter une casquette de lead developper, proposer de nouvelles solutions techniques et être écouté. Je ne cherche donc pas un poste de développeur Web lambda.

Sur Paris intra-muros, si possible centre ou proche. Même si j’aime la présence et le travail en équipe, j’aimerai également avoir la possibilité de pouvoir travailler ponctuellement en télétravail de temps à autre si nécessité (pour éviter les problèmes ou inhérents aux transports par exemple, réceptionner un colis, horaires décalés…).

Mes compétences: C/C++ (Qt), PHP (symfony), Java, SQL, Pl/SQL, Python, Javascript/AJAX (jquery), HTML…
SGBD: PostgreSQL, MySQL, Oracle, Mongodb, Hadoop/Hbase
Méthodologie: Milieux agiles (XP), iso9001:2000
Ayant 3 ans d’expériences dans l’aérospatial, je suis rigoureux, sérieux, très à l’aise dans la rédaction technique (française et anglaise); J’ai des compétences d’encadrement de 1 à 3 salariés sur des périodes de 6 mois à un an.

Informations de contact et CV pour ceux qui auront tout lu et qui, soyons fous, recrutent:

Contact: Par mail uniquement la première fois à pm@monkeyz.eu
CV complet: http://www.monkeyz.eu/~mycroft/CV_Patrick_MARIE.pdf

Vous pouvez également consulter mon profil linkedin, github et bien évidement ce weblog!

A bientôt!

Développeurs: Vous n’êtes pas seuls !

Je suis en pleine réflexion ces temps-ci quant au travail fourni par deux apprentis que j’encadre. Ils sont de niveau bac+2, et j’ai fais pour ma part un stage à ce niveau, donc je peux faire un parallèle entre eux et moi. Et quelque chose me frappe: Ils sont seuls au monde. Quand ils développaient, ils ont oublié qu’il existait des gens autour d’eux, des gens avec qui ils doivent travailler, des gens à qui il faut vendre leur produit et des gens qui doivent utiliser leur produit et à qui il faut assurer un support.

De plus, dans une très petite société (moins de 10), un développeur doit dépasser son contexte. Il doit pouvoir s’adapter à chaque situation, et celle ci peut passer du tout au tout à chaque moment de la journée de travail. Les développeurs l’oublient. Comme ils restent dans leur bulle, ils oublient que d’autres gens vont utiliser ce qu’ils produient. Ces développeurs produisent leur code à leur image, lisent une spec, la code, au mieux la teste, mais oublient tout simplement tout le reste.

⇀ Ils oublient leurs collègues développeurs, en décidant de ne pas respecter les conventions de codage, les règles de nommage, les principes de base, de documenter leur code, de le commenter;

⇀ Ils abandonnent l’ingénieur système, qui met en production leur application, en ne discutant pas avec eux aux moyens de remonter les problèmes (logs), en ne testant pas préalablement les package générés, en développant sur leur système en oubliant la configuration des systèmes en prod, en ne documentant pas les fichiers de configuration, les variables, les comportements attendus en cas de problème;

⇀ Ils ne facilitent pas la vie de la QA, en ne leur fournissant pas les moyens d’exploiter avec satisfaction l’application produite à des fins de tests: En faisant une application inutilisable, la QA prendra le moins de temps possible à la valider, et au final le produit ne sera pas testé. C’est au développeur de définir avec lui les moyens de tests, outils, jeux de données prèts à être utilisés;

⇀ Ils oublient de vendre leur application. Qui n’a jamais été la « victime » de l’effet démo ? Personne. Et la faute à qui ? Une coupure réseau pendant une démo d’une appli sur le net, certes, ça arrive. Mais la plupart du temps, c’est juste la faute du développeur, qui est resté dans sa propre idée de l’utilisation du soft. Il a juste oublié d’imaginer donc de jouer un simple test fonctionnel;

⇀ Et au final, et pour moi le pire, ils ignorent totalement le client final. Et là je me demande à quoi ils servent si ils ne réfléchissent pas un seul instant à cet utilisateur qui va devoir utiliser l’outil qu’ils produisent pour eux au quotidien. Je ne parle pas juste que de l’ergonomie générale de l’application qu’ils auront oublié, du manuel d’utilisation qu’ils n’auront pas rédigé, mais des tests de leur application qu’ils ne prennent même pas la peine de faire (je ne parle pas des tests unitaires, fonctionnels qu’ils sont censés faire !), du bâclage de la correction des bugs, des petits détails qui rendent utilisables le logiciel en question… toutes ces choses qui en font un outil formidable.

Alors, je n’ai qu’un conseil: Regardez autour de vous. Vous n’êtes pas seuls. Vous êtes entourés de gens surement compétants, surement formidables, de clients pressés d’utiliser vos produits (et au final de vous nourrir, pensez-y), alors ne les oubliez pas. Ils sont là, allez leur parler, communiquez, échangez. Pour moi, dans monde idéal, avant de la vendre, le développeur devrait faire tester à plusieurs personnes de sa société plus longtemps qu’un simple test leur application. Ca peut suffire de faire d’un tool qui passerait durement pour un prototype à un outil prêt à mettre en production.