PHP 5.3 et les fonctions anonymes

Tags:: php :: développement

Je les utilise depuis des lustres en Javascript et Java, mais PHP en était dépourvu... les fonctions anonymes ou lambdas. Il existait la méthode create_fonction qui permettait de se débrouiller, mais php 5.3 nous permet une écriture plus instinctive, plus proche des deux langages que j'ai cité en premier et surtout une optimisation lors de la création/appel.

La page http://blog.pascal-martin.fr/post/php-5.3-1-closures-et-lambdas est très descriptive de son utilisation. Vous pouvez justement voir un profiling des deux méthodes existante et vous rendre compte de l'optimisation de PHP 5.3 par rapport à create_function. Alors vous me direz: mais à quoi ça sert ? Laissez moi vous expliquer.

Lorsque que l'on code une classe, on déclare en général des méthodes (fonctions de classe) qui vont pouvoir être appelées selon l'encapsulation de la classe. Lorsque PHP parse le code, il voit la méthode et l'enregistre en faisant attention qu'il n'y ait pas d'erreur de syntaxe etc... Cela prend un peu de temps. Seulement parfois, un fonction n'est utile que dans des cas assez rares, pour faire de petites opérations, appelé dans un cas très spécial... déclarer un méthode qui prendra à coup sûr un peu de temps au parseur dans tout les cas alors que cette fonction ne sert qu'à un endroit est très dommage. C'est là que la fonction anonyme est franchement utile.

Cela ressemble fort aux fonction inline que l'on trouve en C++, ces fonctions sont compilées à la volée au moment de l'appel. Cela fait gagner beaucoup de temps processeur mais aussi en terme de lecture de code. Là où l'on peut se rendre compte de l'intérêt de lambdas c'est lors de l'utilisation des fonctions PHP qui permettent un callback. Par exemple, preg_replace_callback permet de remplacer un patron de recherche par des valeurs retournées par une fonction. Voici un exemple à l'ancienne, puis avec un lambdas:


class Lambdas {

    function myReplace($matches){
        if(strlen($matches[1]) == 4){
            //premier nombre = année
            $date = mktime(0,0,0,matches[2],$matches[3],$matches[1]);
            return date('r',$date);
        }
        $date = mktime(0,0,0,matches[1],$matches[2],$matches[3]);
        return date('r',$date);
       
    }

    function foo(){
        $str = "Exemple, je cherche des date comme 2009/01/06 ou 01-03-2009 pour les formater en vrai date";
        $str = preg_replace_callback ('/(\d+)[\/\-](\d+)[\/\-](\d+)/','Lambdas::myReplace',$str);
        echo $str;
    }

}
 

Ici, on a déclaré une méthode qui doit être (en plus...) public afin de l'appeler via le callback. Pas franchement sympa en terme d'implémentation, et qui plus est il faudra que PHP imbrique la méthode (ou la fonction si vous sortez myReplace de la classe) au moment du parsing.

Maintenant nous passons par un lambdas:


class Lambdas {

    function foo(){
        $str = "Exemple, je cherche des date comme 2009/01/06 ou 01-03-2009 pour les formater en vrai date";
        $str = preg_replace_callback ('/(\d+)[\/\-](\d+)[\/\-](\d+)/',function ($matches){
            if(strlen($matches[1]) == 4){
                //premier nombre = année
                $date = mktime(0,0,0,matches[2],$matches[3],$matches[1]);
                return date('r',$date);
            }
            $date = mktime(0,0,0,matches[1],$matches[2],$matches[3]);
            return date('r',$date);
        },$str);
       
    }

}
 

Et voilà, cette fonction n'étant utile que dans la méthode "foo" il n'y avait pas d'intérêt à la déclarer dans la classe ou en dehors. Mieux encore, cette méthode sera "compilée" si et seulement si on appelle la méthode "foo" !

Et comme vous l'aurez vu sur la page de Pascal Martin, la compilation est très rapide, surtout comparé à create_function.

Un dernier exemple, imaginons que foo puisse prendre en argument un cas... par exemple:


class Lambdas {

    function foo($formamt){
        $str = "Exemple, je cherche des date comme 2009/01/06 ou 01-03-2009 pour les formater en vrai date";

        //on crée la fonction que nous voulons, si $format vaut "date" on
        //retourne une date, sinon on timestamp
        if($format == "date"){
            $func = function ($matches){
                if(strlen($matches[1]) == 4){
                    //premier nombre = année
                    $date = mktime(0,0,0,matches[2],$matches[3],$matches[1]);
                    return date('r',$date);
                }
                $date = mktime(0,0,0,matches[1],$matches[2],$matches[3]);
                return date('r',$date);
            };
        }else{
            $func = function ($matches){
                if(strlen($matches[1]) == 4){
                    //premier nombre = année
                    return  mktime(0,0,0,matches[2],$matches[3],$matches[1]);                   
                }
                return  mktime(0,0,0,matches[1],$matches[2],$matches[3]);                 
            };
        }

        //et on applique:
        $str = preg_replace_callback ('/(\d+)[\/\-](\d+)[\/\-](\d+)/',$func,$str);
       
    }

}
 

Ici, nous créons la fonction nécessaire selon un cas.

Pour le moment, vous ne trouverez cette technique que dans PHP≥5.3, donc sur peu de configuration pour le moment, mais ça ne saurais tarder :)

PS: Le code est mal mis en forme à cause de mon design trop sérré... je vais reprendre la charte pour l'adapter à mon besoin... c'est à dire avoir plus de largeur d'écriture

Utilisez le code barre pour ouvrir le ticket dans votre mobile:
This ticket on you mobile

Pas de commentaire pour le moment

Ajouter un commentaire
Veuillez répondre à la question suivante : Tapez "clap" sans guillemets dans le champs suivant

Trackbacks

Pour ajouter un trackback (retrolien) sur ce ticket, utilisez cette adresse: http://www.metal3d.org/index.php/trackback/default/tb?id=blog%2F179

Tags

Blog Copix Communication PC Config Fedora Vidéo Humour Autre Web Materiel Informatique PHP Développement Mootools HTML Linux WEB IE CSS Vista Microsoft Sympa XHTML Quizz Widget Klik CWE Voeux Bonne année Musique CCRMA Son Audio MAO Reconnaissance vocale Windows Mac Compiz MacOS Mysql Sun Base de données BD Screenlets Screenlet RPM compiz Ubuntu Live FireFox Derambarsh Facebook media informations Sécurité javascript SSH Commande Marketing concours ipod wii QT Trooltech Nokia Libre Logiciels GPL Attali Gnome Dock Compiler Bench undelete reiserfs recovery recover Thread Serveur Optimisation Server Apache Album RSS Flash Air XML Firefox Blender Opensource Orange Internet LiveBox Animaux Droits Logiciels Libres Google Loi RBS netcat Bash Téléphone Spam 3D NIDIA Standards Widgets Merise UML Streaming Developpement Perl MySQL Firewall Parfeu Bayes Novell Réseau Python LVS Salon FTP Dedibox Chrome Administration IRC Gentoo troll video Nouveauté Finance Etudiant spéctacle OpenOffice Javascript Java Info Eclpise ATI design mootools KDE Bureau Design GNU C Pages Jaunes Fun Bijoux Art mail Admin vmware fedora linux VirtualBox VMWare Qemu KVM vim Grep Fglrx Webkit GTK google web JQuery Coup de gueule coup de gueule Lois SVG Raycaster Canvas Hadopi Desktop Jeux Les Sims développement astuces Screen firefox Mobile Safaru Wine bash commande astuce Wave ooc C++ C# Netbook Hercules Bureautique Twitter Safari W3C chrome kazehakaze midori navigateur gecko webkit Links Liens Pyhon Nouvelles Metal Perso Conférence JDLL PCC Roadsend OOC News Acteur Cinéma Chanteur Seven windows orthographe pcc php jdll Slide Application mysql Html twitter python screen curses SVN Android Gphone iPhone OpenGL MindMap Projet Javascrtip Ajax Guitare Tab Tablature JSON firebug Chromium Iphone Titanium music sound android ogg ogv streaming Arkyne svn subversion gnome VLC Tv encoder ffmpeg Cryptage apple microsoft HTML5 Max Apple code youtube quvi git uzbl webgl chromium

  Catalogue professionnel de musique libre


  • twitter entries...
follow me on Twitter

Valid XHTML 1.0 Strict

tumblr visitor