SlideShare a Scribd company logo
1 of 78
Download to read offline
Jouons avec PHP 5.3

Fabien Potencier
Fabien Potencier
•  Serial entrepreneur et développeur par passion
•  Fondateur de Sensio (1998)
   –  Société de conseil
      autour des technologies Open-Source
      (France and USA)
   –  70 personnes
   –  Clients grands comptes
   –  Sponsor de projets Open-Source
      comme Symfony, Doctrine ou Swift Mailer
Fabien Potencier

•  Mon blog technique : http://fabien.potencier.org/

•  Sur Twitter : http://www.twitter.com/fabpot

•  Mon code sur Github: http://github.com/fabpot/
Migrer vers PHP 5.3
Des raisons techniques
Migrer vers PHP 5.3 ?
•  Pourquoi ?
   –  Plus rapide
   –  Moins de mémoire


•  Quand ?
   –  PHP 5.3.0 est déjà stable depuis quelques mois
   –  PHP 5.3.1 va bientôt être disponible
   –  La migration est simple
PHP 5.3
Beaucoup plus rapide ?
Dmitry Stogov a fait quelques tests de performance
                     pour des applications PHP connues

                            Drupal 20% faster
                             Typo3 30% faster
                          Wordpress 15% faster
                             Xoops 10% faster

http://news.php.net/php.internals/36484
Doctrine 1.X and 2.0
Significativement plus rapide avec PHP 5.3


30% de mémoire en moins

       20% plus rapide
symfony 1.X




                                                                                                   -47%


symfony project running on PHP 5.2 vs PHP 5.3 profiled with XHPROF (run 4aeeb7d54b732 is PHP 5.3)
Migrer vers PHP 5.3
Des raisons fonctionnelles
Migrer vers PHP 5.3, frameworks 2.0
•  Prochaines versions des principaux frameworks/bibliothèques seront
   basés sur PHP 5.3
   –  Symfony 2.0
   –  Doctrine 2.0
                                   Fin 2010
   –  Zend Framework 2.0


•  Interopérabilité améliorée entre ces bibliothèques,
   grâce aux namespaces
PHP 5.3 technical interoperability standards

           « … describes the mandatory requirements
                     that must be adhered to
                 for autoloader interoperability »


http://groups.google.com/group/php-standards/web/final-proposal
Pourquoi ?
•  Les bibliothèques respectant cette spécification simple
   –  seront techniquement 100% interopérable
   –  pourront partager un seul autoloader optimisé
•  Par exemple pour utiliser Symfony 2.0 + Doctrine 2.0 + Zend
   Framework 2.0 dans un même projet
   –  Un unique autoloader pour les 3 bibliothèques
   –  Exemple d’implémentation: http://gist.github.com/221634
   –  Sera certainement implémenté en C une fois le standard définitif
Les namespaces dans Symfony 2
SymfonyComponents
SymfonyFoundation
SymfonyFramework

SymfonyComponentsEventDispatcherEvent
SymfonyFoundationClassLoader
SymfonyComponentsEventDispatcherEvent


                   vs


                sfEvent

                           L e nom des classes
                           n’es t pas plus court !
Les namespaces dans Symfony 2
$classLoader = new ClassLoader('Symfony', __DIR__.'/lib');
$classLoader->register();

$container = new Builder();
$loader = new XmlFileLoader($container, __DIR__);
$loader->load('services.xml');

$dumper = new PhpDumper($container);
echo $dumper->dump();
Les namespaces dans Symfony 2
require __DIR__.'/lib/Symfony/Core/ClassLoader.php';

use SymfonyFoundationClassLoader;
use SymfonyComponentsDependencyInjectionBuilder;
use SymfonyComponentsDependencyInjectionReference;
use SymfonyComponentsDependencyInjectionLoader
XmlFileLoader;
use SymfonyComponentsDependencyInjectionDumperPhpDumper;




                                              Bonne pratique
PHP 5.3
L’apport pour les entreprises
PHP 5 dans les entreprises
Depuis 2005 et l’arrivée de PHP 5.0 et surtout PHP 5.2

      Adoption plus rapide dans les entreprises
              que dans la communauté

        Rupture technologique qui a entraîné
              une révolution des usages
PHP 5, une rupture technologique
•  Arrivée de frameworks matures : symfony, Zend Framework, CakePHP,
   Prado, …
•  Professionnalisation des développements
   –  Prise en compte des bonnes pratiques : tests, design patterns, sécurité, …
•  Professionnalisation des développeurs
   –  Passage d’une communauté de bidouilleurs à une communauté de
      développeurs PHP professionnels
   –  Une communauté qui se scinde en deux
L’adoption de PHP 5.3 devrait être rapide dans les entreprises
   –  Migration facile
   –  Support Windows amélioré (rapidité, intégration, fonctionnalités)
   –  Meilleures performances (for free)
   –  Apport technique limité…
   –  … mais les usages vont une nouvelle fois évoluer
PHP 5.3 dans les entreprises en 2010/2011

•  Une évolution technologique qui va permettre de continuer le
   changement des usages et accélérer l’adoption massive de PHP dans les
   entreprises

•  Ce changement devrait être une fois encore mené par les frameworks
PHP 5.3
Parlons technique…
PHP 5.3
•  Beaucoup de nouveautés

   –  Cosmétiques : __DIR__, ?:, NOWDOC, …

   –  Fonctionnelles : i18n, SPL, gestion des dates, mysqlnd, …

   –  Structurelles : namespaces, fonctions anonymes, closures, late static binding,
      phar, support Windows, …
PHP 5.3
Le singleton
Le singleton nuit gravement
   à la santé de votre code
sfContext dans symfony
  est “juste” l’exception
 qui confirme la règle ;)
Le Singleton à travers les âges
Le Singleton en PHP 4
    Pas vraiment possible à cause des limitations du language
class Singleton
{
  function &getInstance()
  {
    static $instance;

        if (!$instance)
        {
          $instance = new Singleton();
        }
                                                        on peut toujours
        return $instance;                              in stancier la classe
}
    }
                                                            directement
$obj =& singleton::getInstance();
Le Singleton en PHP 5.0/5.1/5.2
class Singleton
{
  static private $instance;

    private function __construct() {}

    static public function getInstance()
    {
      if (null === self::$instance)
      {
        self::$instance = new self();
      }

        return self::$instance;
    }                                            ne pas oublier la
    final private function __clone() {}         mé thode __clone()
}

$obj = Singleton::getInstance();
Le Singleton en PHP 5.3
abstract class Singleton
{
  private static $instances = array();

    final private function __construct()
    {
      if (isset(self::$instances[get_called_class()]))
      {
        throw new Exception("An instance of ".get_called_class()." already exists.");
      }
      static::initialize();
    }

    protected function initialize() {}

    final public static function getInstance()
    {
      $class = get_called_class();
      if (!isset(self::$instances[$class]))
      {
        self::$instances[$class] = new static();
      }
      return self::$instances[$class];
    }

    final private function __clone() {}
}
Le Singleton en PHP 5.3

class Foo extends Singleton {}
class Bar extends Singleton {}

$a = Foo::getInstance();
$b = Bar::getInstance();
Late Static Binding
        __callStatic()



        User::find(1)

User::findByUsername('fabien');
Fonctions anonymes
Fonctions Anonymes

           Une fonction anonyme est une fonction
                 déclarée à la volée (sans nom)

function () { echo 'Hello world!'; };
Fonctions Anonymes

              Pour être affectée à une variable



$hello = function () { echo 'Hello world!'; };
Fonctions Anonymes

                  Puis être utilisée


$hello();


call_user_func($hello);
Fonctions Anonymes

          et/ou être passé en argument d’une fonction

function foo(Closure $func)
{
  $func();
}

foo($hello);
Fonctions anonymes
$hello = function ($name) { echo 'Hello '.$name; };

$hello('Fabien');

call_user_func($hello, 'Fabien');

function foo(Closure $func, $name)
{
  $func($name);
}

foo($hello, 'Fabien');
Que faire avec
des fonctions anonymes ?
array_*
Simplification de l’usage de

  array_map()

  array_reduce()

  array_filter()
Comment récupérer un tableau avec les titres des objets ?
class Article
{
  public function __construct($title)
  {
    $this->title = $title;
  }

    public function getTitle()
    {
      return $this->title;
    }
}

$articles = array(
   new Article('Forum PHP 2009 - part 1'),
   new Article('Forum PHP 2009 - part 2'),
   new Article('Vivement Noël !'),
);
$titles = array();
foreach ($articles as $article)
{
  $titles[] = $article->getTitle();
}

                                                                            100         100
$titles = array_map(create_function('$article', 'return $article->getTitle();'), $articles);

                                                                            300         1800
$titles = array_map(function ($article) { return $article->getTitle(); }, $articles);

                                                                            100         200
$mapper = function ($article) { return $article->getTitle(); };
$titles = array_map($mapper, $articles);

                                                                            100         180

      mémoire       rapidité
Une closure est une fonction anonyme
      qui se souvient du contexte
    dans laquelle elle a été crée…
$method = 'getTitle';

$mapper = function ($article) use($method)
{
   return $article->$method();
};

$titles = array_map($mapper, $articles);
$mapper = function ($method)
{
   return function ($article) use($method)
   {
      return $article->$method();
   };
};

$titles = array_map($mapper('getTitle'), $articles);
Questions ?
Injection de Dépendance
« Dependency Injection is where components
 are given their dependencies through their
constructors, methods, or directly into fields. »

http://www.picocontainer.org/injection.html
class Message
{
  public function __construct(array $options)
  {
    $this->output = new FancyOutput();

        // ...
    }

    // ...
}


Impossible de changer la classe FancyOutput par une autre
class Message
{
  public function __construct(OutputInterface $output, array $options)
  {
    $this->output = $output;
    $this->options = array_merge(array('with_newline' => false), $options);
  }

    public function say($msg)
    {
       $this->output->render($msg.($this->options['with_newline'] ? "n" : ''));
    }
}
interface OutputInterface
{
  public function render($msg);
}


class Output implements OutputInterface
{
  public function render($msg)
  {
    echo $msg;
  }
}


class FancyOutput implements OutputInterface
{
  public function render($msg)
  {
    echo sprintf("033[33m%s033[0m", $msg);
  }
}
$output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));
$message->say('Hello World');
Un container DI permet
de décrire les objets et leurs relations

           de les configurer

             de les créer
class DIContainer
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {
      if (is_callable($this->values[$id]))
      {
        return $this->values[$id]($this);
      }
      else
      {
        return $this->values[$id];
      }
    }
}
// define the parameters
$container->output_class = 'FancyOutput';
$container->with_newline = true;

// defined the objects
$container->message = function ($c)
{
   return new Message($c->output, array('with_newline' => $c->with_newline));
};

$container->output = function ($c)
{
   return new $c->output_class();
};

// get the message object
$container->message->say('Hello World');
spl_object_hash($container->message)



              !==
spl_object_hash($container->message)
$container->message = function ($c)
{
  static $object;

  if (is_null($object))
  {
    $object = new Message($c->output, array('with_newline' => $c->with_newline));
  }

  return $object;
};
spl_object_hash($container->message)



              ===
spl_object_hash($container->message)
function asShared($callable)
{
  return function ($c) use ($callable)
  {
    static $object;

      if (is_null($object))
      {
        $object = $callable($c);
      }
      return $object;
    };
}
$container->message = $container->asShared(function ($c)
{
  return new Message(
     $c->output,
     array('with_newline' => $c->with_newline)
  );
});
class DIContainer
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {
      if (!isset($this->values[$id]))
      {
        throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));
      }

        if (is_callable($this->values[$id]))
        {
          return $this->values[$id]($this);
        }
        else
        {
          return $this->values[$id];
        }
    }
}
class DIContainer
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $value;
    }

    function __get($id)
    {
      if (!isset($this->values[$id]))
      {
        throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id));
      }

        if (is_callable($this->values[$id]))
        {
          return $this->values[$id]($this);
        }
        else
        {
          return $this->values[$id];
        }
    }

    function asShared($callable)
    {
      return function ($c) use ($callable)
      {
        static $object;                                                                      40 LOC pour un
          if (is_null($object))
          {
            $object = $callable($c);
                                                                                          co ntainer DI complet
          }
          return $object;
        };
    }
}
plus d’infos…

http://fabien.potencier.org/article/17/on-php-5-3-lambda-functions-and-closures



http://components.symfony-project.org/dependency-injection/


http://github.com/fabpot/pimple



http://twittee.org/
Twittee: A Dependency Injection Container in a tweet
•  Implementation does not use PHP 5.3
•  Its usage needs PHP 5.3


class Container {
  protected $s=array();
  function __set($k, $c) { $this->s[$k]=$c; }
  function __get($k) { return $this->s[$k]($this); }
}

                                  witte e.org
                                t
Questions ?
Observateur
Un objet (sujet)
maintient une liste d’observateurs
et les informe automatiquement
  des changements intervenus
    en appelant une méthode
Un dispatcher est un point central
permettant de gérer les connections
 entre les sujets et les observateurs
// an anonymous listener
$listener = function ($parameters)
{
   echo "Hello {$parameters['name']}n";
};



// register the listener with the dispatcher
$dispatcher = new EventDispatcher(array(
  'foo' => $listener,
));



// notify the event somewhere
$dispatcher->notify('foo', array('name' => 'Fabien'));
class EventDispatcher
{
  function __construct($listeners)
  {
    $this->listeners = $listeners;
  }

    function notify($name, $parameters = array())
    {
      $this->listeners[$name]($parameters);
    }
}
Comment enregistrer plusieurs observateurs ?



$listener = new EventListeners(
   function ($parameters) { echo "Hello {$parameters['name']}?n"; },
   function ($parameters) { echo "Hello {$parameters['name']}!n"; }
);

$dispatcher = new EventDispatcher(array(
  'foo' => $listener
));

$dispatcher->notify('foo', array('name' => 'Fabien'));
class EventListeners
{
  function __construct()
  {
    $this->listeners = func_get_args();
  }

    function __invoke($parameters = array())
    {
      foreach ($this->listeners as $listener)
      {
        $listener($parameters);
      }
    }
}
symfony-live.com
           with Matthew Weier O’Pheinney




    I will reveal the first alpha release of Symfony 2.0!
symfony-live.com
          with Matthew Weier O’Pheinney




   … with Matthew Weier O'Phinney as a special guest
Questions?
Sensio S.A.
    92-98, boulevard Victor Hugo
        92 115 Clichy Cedex
              FRANCE
       Tél. : +33 1 40 99 80 80

               Contact
           Fabien Potencier
    fabien.potencier at sensio.com




  http://www.sensiolabs.com/
http://www.symfony-project.org/
 http://fabien.potencier.org/

More Related Content

What's hot

PHP 1 - Apprendre les bases
PHP 1 - Apprendre les basesPHP 1 - Apprendre les bases
PHP 1 - Apprendre les basesPierre Faure
 
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...Frederic Hardy
 
JavaScript prise en main et fondamentaux
JavaScript prise en main et fondamentauxJavaScript prise en main et fondamentaux
JavaScript prise en main et fondamentauxVincent Petetin
 
cpp1 : Quelques elements de base du C++
cpp1 : Quelques elements de base du C++cpp1 : Quelques elements de base du C++
cpp1 : Quelques elements de base du C++Abdoulaye Dieng
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDOAbdoulaye Dieng
 
Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4halleck45
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Kristen Le Liboux
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationECAM Brussels Engineering School
 
Exploiter php 5
Exploiter php 5Exploiter php 5
Exploiter php 5halleck45
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScriptKristen Le Liboux
 
Initiation à l'algorithmique
Initiation à l'algorithmiqueInitiation à l'algorithmique
Initiation à l'algorithmiqueAbdoulaye Dieng
 

What's hot (18)

Ce bon vieux propel
Ce bon vieux propelCe bon vieux propel
Ce bon vieux propel
 
PHP 1 - Apprendre les bases
PHP 1 - Apprendre les basesPHP 1 - Apprendre les bases
PHP 1 - Apprendre les bases
 
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
 
Cours php
Cours phpCours php
Cours php
 
JavaScript prise en main et fondamentaux
JavaScript prise en main et fondamentauxJavaScript prise en main et fondamentaux
JavaScript prise en main et fondamentaux
 
cpp1 : Quelques elements de base du C++
cpp1 : Quelques elements de base du C++cpp1 : Quelques elements de base du C++
cpp1 : Quelques elements de base du C++
 
php2 : formulaire-session-PDO
php2 : formulaire-session-PDOphp2 : formulaire-session-PDO
php2 : formulaire-session-PDO
 
Introduction au Jquery
Introduction au JqueryIntroduction au Jquery
Introduction au Jquery
 
Php cours
Php coursPhp cours
Php cours
 
Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4Programmation Orientée Objet et les Traits en PHP 5.4
Programmation Orientée Objet et les Traits en PHP 5.4
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5
 
Les listes en Python
Les listes en PythonLes listes en Python
Les listes en Python
 
Programmation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulationProgrammation orientée objet : Object, classe et encapsulation
Programmation orientée objet : Object, classe et encapsulation
 
Exploiter php 5
Exploiter php 5Exploiter php 5
Exploiter php 5
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Introduction à jQuery
Introduction à jQueryIntroduction à jQuery
Introduction à jQuery
 
Initiation à l'algorithmique
Initiation à l'algorithmiqueInitiation à l'algorithmique
Initiation à l'algorithmique
 
Nouveautés php 7
Nouveautés php 7Nouveautés php 7
Nouveautés php 7
 

Similar to Playing With PHP 5.3

Php 7.4 2020-01-28 - afup
Php 7.4   2020-01-28 - afupPhp 7.4   2020-01-28 - afup
Php 7.4 2020-01-28 - afupJulien Vinber
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHPjulien pauli
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Engineor
 
Migration PHP4-PHP5
Migration PHP4-PHP5Migration PHP4-PHP5
Migration PHP4-PHP5julien pauli
 
Mieux Développer en PHP avec Symfony
Mieux Développer en PHP avec SymfonyMieux Développer en PHP avec Symfony
Mieux Développer en PHP avec SymfonyHugo Hamon
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web5pidou
 
"Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?""Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?"o2sources
 
Function oop - bonnes pratiques ms tech days
Function   oop - bonnes pratiques ms tech daysFunction   oop - bonnes pratiques ms tech days
Function oop - bonnes pratiques ms tech daysJean-Pierre Vincent
 
Patterns et bonnes pratiques autour de JavaScript
Patterns et bonnes pratiques autour de JavaScriptPatterns et bonnes pratiques autour de JavaScript
Patterns et bonnes pratiques autour de JavaScriptMicrosoft Technet France
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsVladyslav Riabchenko
 
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...fdussert
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonyVincent Composieux
 
PHP 5.3, PHP Next
PHP 5.3, PHP NextPHP 5.3, PHP Next
PHP 5.3, PHP NextSQLI
 
Introduction à Symfony2
Introduction à Symfony2Introduction à Symfony2
Introduction à Symfony2Hugo Hamon
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentationjulien pauli
 
Javascript : fondamentaux et OOP
Javascript : fondamentaux et OOPJavascript : fondamentaux et OOP
Javascript : fondamentaux et OOPJean-Pierre Vincent
 

Similar to Playing With PHP 5.3 (20)

Php 7.4 2020-01-28 - afup
Php 7.4   2020-01-28 - afupPhp 7.4   2020-01-28 - afup
Php 7.4 2020-01-28 - afup
 
Php 5.3
Php 5.3Php 5.3
Php 5.3
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !
 
Migration PHP4-PHP5
Migration PHP4-PHP5Migration PHP4-PHP5
Migration PHP4-PHP5
 
Mieux Développer en PHP avec Symfony
Mieux Développer en PHP avec SymfonyMieux Développer en PHP avec Symfony
Mieux Développer en PHP avec Symfony
 
Php4 Mysql
Php4 MysqlPhp4 Mysql
Php4 Mysql
 
Quelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application webQuelle place pour le framework Rails dans le développement d'application web
Quelle place pour le framework Rails dans le développement d'application web
 
"Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?""Un module Prestashop, comment ca marche?"
"Un module Prestashop, comment ca marche?"
 
Function oop - bonnes pratiques ms tech days
Function   oop - bonnes pratiques ms tech daysFunction   oop - bonnes pratiques ms tech days
Function oop - bonnes pratiques ms tech days
 
Patterns et bonnes pratiques autour de JavaScript
Patterns et bonnes pratiques autour de JavaScriptPatterns et bonnes pratiques autour de JavaScript
Patterns et bonnes pratiques autour de JavaScript
 
SOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applicationsSOLID : les principes à l’origine du succès de Symfony et de vos applications
SOLID : les principes à l’origine du succès de Symfony et de vos applications
 
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
Atoum, le framework de tests unitaires pour PHP 5.3 simple, moderne et intuit...
 
Soutenance Zend Framework vs Symfony
Soutenance Zend Framework vs SymfonySoutenance Zend Framework vs Symfony
Soutenance Zend Framework vs Symfony
 
PHP 5.3, PHP Next
PHP 5.3, PHP NextPHP 5.3, PHP Next
PHP 5.3, PHP Next
 
Zf2 ce-qui-va-changer
Zf2 ce-qui-va-changerZf2 ce-qui-va-changer
Zf2 ce-qui-va-changer
 
Introduction à Symfony2
Introduction à Symfony2Introduction à Symfony2
Introduction à Symfony2
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentation
 
Javascript : fondamentaux et OOP
Javascript : fondamentaux et OOPJavascript : fondamentaux et OOP
Javascript : fondamentaux et OOP
 
Php1
Php1Php1
Php1
 

More from Fabien Potencier

Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien Potencier
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Fabien Potencier
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Fabien Potencier
 

More from Fabien Potencier (20)

Varnish
VarnishVarnish
Varnish
 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 

Playing With PHP 5.3

  • 1. Jouons avec PHP 5.3 Fabien Potencier
  • 2. Fabien Potencier •  Serial entrepreneur et développeur par passion •  Fondateur de Sensio (1998) –  Société de conseil autour des technologies Open-Source (France and USA) –  70 personnes –  Clients grands comptes –  Sponsor de projets Open-Source comme Symfony, Doctrine ou Swift Mailer
  • 3. Fabien Potencier •  Mon blog technique : http://fabien.potencier.org/ •  Sur Twitter : http://www.twitter.com/fabpot •  Mon code sur Github: http://github.com/fabpot/
  • 4. Migrer vers PHP 5.3 Des raisons techniques
  • 5. Migrer vers PHP 5.3 ? •  Pourquoi ? –  Plus rapide –  Moins de mémoire •  Quand ? –  PHP 5.3.0 est déjà stable depuis quelques mois –  PHP 5.3.1 va bientôt être disponible –  La migration est simple
  • 7.
  • 8. Dmitry Stogov a fait quelques tests de performance pour des applications PHP connues Drupal 20% faster Typo3 30% faster Wordpress 15% faster Xoops 10% faster http://news.php.net/php.internals/36484
  • 9. Doctrine 1.X and 2.0 Significativement plus rapide avec PHP 5.3 30% de mémoire en moins 20% plus rapide
  • 10. symfony 1.X -47% symfony project running on PHP 5.2 vs PHP 5.3 profiled with XHPROF (run 4aeeb7d54b732 is PHP 5.3)
  • 11. Migrer vers PHP 5.3 Des raisons fonctionnelles
  • 12. Migrer vers PHP 5.3, frameworks 2.0 •  Prochaines versions des principaux frameworks/bibliothèques seront basés sur PHP 5.3 –  Symfony 2.0 –  Doctrine 2.0 Fin 2010 –  Zend Framework 2.0 •  Interopérabilité améliorée entre ces bibliothèques, grâce aux namespaces
  • 13. PHP 5.3 technical interoperability standards « … describes the mandatory requirements that must be adhered to for autoloader interoperability » http://groups.google.com/group/php-standards/web/final-proposal
  • 14. Pourquoi ? •  Les bibliothèques respectant cette spécification simple –  seront techniquement 100% interopérable –  pourront partager un seul autoloader optimisé •  Par exemple pour utiliser Symfony 2.0 + Doctrine 2.0 + Zend Framework 2.0 dans un même projet –  Un unique autoloader pour les 3 bibliothèques –  Exemple d’implémentation: http://gist.github.com/221634 –  Sera certainement implémenté en C une fois le standard définitif
  • 15. Les namespaces dans Symfony 2 SymfonyComponents SymfonyFoundation SymfonyFramework SymfonyComponentsEventDispatcherEvent SymfonyFoundationClassLoader
  • 16. SymfonyComponentsEventDispatcherEvent vs sfEvent L e nom des classes n’es t pas plus court !
  • 17. Les namespaces dans Symfony 2 $classLoader = new ClassLoader('Symfony', __DIR__.'/lib'); $classLoader->register(); $container = new Builder(); $loader = new XmlFileLoader($container, __DIR__); $loader->load('services.xml'); $dumper = new PhpDumper($container); echo $dumper->dump();
  • 18. Les namespaces dans Symfony 2 require __DIR__.'/lib/Symfony/Core/ClassLoader.php'; use SymfonyFoundationClassLoader; use SymfonyComponentsDependencyInjectionBuilder; use SymfonyComponentsDependencyInjectionReference; use SymfonyComponentsDependencyInjectionLoader XmlFileLoader; use SymfonyComponentsDependencyInjectionDumperPhpDumper; Bonne pratique
  • 19. PHP 5.3 L’apport pour les entreprises
  • 20. PHP 5 dans les entreprises Depuis 2005 et l’arrivée de PHP 5.0 et surtout PHP 5.2 Adoption plus rapide dans les entreprises que dans la communauté Rupture technologique qui a entraîné une révolution des usages
  • 21. PHP 5, une rupture technologique •  Arrivée de frameworks matures : symfony, Zend Framework, CakePHP, Prado, … •  Professionnalisation des développements –  Prise en compte des bonnes pratiques : tests, design patterns, sécurité, … •  Professionnalisation des développeurs –  Passage d’une communauté de bidouilleurs à une communauté de développeurs PHP professionnels –  Une communauté qui se scinde en deux
  • 22. L’adoption de PHP 5.3 devrait être rapide dans les entreprises –  Migration facile –  Support Windows amélioré (rapidité, intégration, fonctionnalités) –  Meilleures performances (for free) –  Apport technique limité… –  … mais les usages vont une nouvelle fois évoluer
  • 23. PHP 5.3 dans les entreprises en 2010/2011 •  Une évolution technologique qui va permettre de continuer le changement des usages et accélérer l’adoption massive de PHP dans les entreprises •  Ce changement devrait être une fois encore mené par les frameworks
  • 25. PHP 5.3 •  Beaucoup de nouveautés –  Cosmétiques : __DIR__, ?:, NOWDOC, … –  Fonctionnelles : i18n, SPL, gestion des dates, mysqlnd, … –  Structurelles : namespaces, fonctions anonymes, closures, late static binding, phar, support Windows, …
  • 27. Le singleton nuit gravement à la santé de votre code
  • 28. sfContext dans symfony est “juste” l’exception qui confirme la règle ;)
  • 29. Le Singleton à travers les âges
  • 30. Le Singleton en PHP 4 Pas vraiment possible à cause des limitations du language class Singleton { function &getInstance() { static $instance; if (!$instance) { $instance = new Singleton(); } on peut toujours return $instance; in stancier la classe } } directement $obj =& singleton::getInstance();
  • 31. Le Singleton en PHP 5.0/5.1/5.2 class Singleton { static private $instance; private function __construct() {} static public function getInstance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } ne pas oublier la final private function __clone() {} mé thode __clone() } $obj = Singleton::getInstance();
  • 32. Le Singleton en PHP 5.3 abstract class Singleton { private static $instances = array(); final private function __construct() { if (isset(self::$instances[get_called_class()])) { throw new Exception("An instance of ".get_called_class()." already exists."); } static::initialize(); } protected function initialize() {} final public static function getInstance() { $class = get_called_class(); if (!isset(self::$instances[$class])) { self::$instances[$class] = new static(); } return self::$instances[$class]; } final private function __clone() {} }
  • 33. Le Singleton en PHP 5.3 class Foo extends Singleton {} class Bar extends Singleton {} $a = Foo::getInstance(); $b = Bar::getInstance();
  • 34. Late Static Binding __callStatic() User::find(1) User::findByUsername('fabien');
  • 36. Fonctions Anonymes Une fonction anonyme est une fonction déclarée à la volée (sans nom) function () { echo 'Hello world!'; };
  • 37. Fonctions Anonymes Pour être affectée à une variable $hello = function () { echo 'Hello world!'; };
  • 38. Fonctions Anonymes Puis être utilisée $hello(); call_user_func($hello);
  • 39. Fonctions Anonymes et/ou être passé en argument d’une fonction function foo(Closure $func) { $func(); } foo($hello);
  • 40. Fonctions anonymes $hello = function ($name) { echo 'Hello '.$name; }; $hello('Fabien'); call_user_func($hello, 'Fabien'); function foo(Closure $func, $name) { $func($name); } foo($hello, 'Fabien');
  • 41. Que faire avec des fonctions anonymes ?
  • 42. array_* Simplification de l’usage de array_map() array_reduce() array_filter()
  • 43. Comment récupérer un tableau avec les titres des objets ? class Article { public function __construct($title) { $this->title = $title; } public function getTitle() { return $this->title; } } $articles = array( new Article('Forum PHP 2009 - part 1'), new Article('Forum PHP 2009 - part 2'), new Article('Vivement Noël !'), );
  • 44. $titles = array(); foreach ($articles as $article) { $titles[] = $article->getTitle(); } 100 100 $titles = array_map(create_function('$article', 'return $article->getTitle();'), $articles); 300 1800 $titles = array_map(function ($article) { return $article->getTitle(); }, $articles); 100 200 $mapper = function ($article) { return $article->getTitle(); }; $titles = array_map($mapper, $articles); 100 180 mémoire rapidité
  • 45. Une closure est une fonction anonyme qui se souvient du contexte dans laquelle elle a été crée…
  • 46. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $titles = array_map($mapper, $articles);
  • 47. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; }; $titles = array_map($mapper('getTitle'), $articles);
  • 50. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » http://www.picocontainer.org/injection.html
  • 51. class Message { public function __construct(array $options) { $this->output = new FancyOutput(); // ... } // ... } Impossible de changer la classe FancyOutput par une autre
  • 52. class Message { public function __construct(OutputInterface $output, array $options) { $this->output = $output; $this->options = array_merge(array('with_newline' => false), $options); } public function say($msg) { $this->output->render($msg.($this->options['with_newline'] ? "n" : '')); } }
  • 53. interface OutputInterface { public function render($msg); } class Output implements OutputInterface { public function render($msg) { echo $msg; } } class FancyOutput implements OutputInterface { public function render($msg) { echo sprintf("033[33m%s033[0m", $msg); } }
  • 54. $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');
  • 55. Un container DI permet de décrire les objets et leurs relations de les configurer de les créer
  • 56. class DIContainer { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } }
  • 57. // define the parameters $container->output_class = 'FancyOutput'; $container->with_newline = true; // defined the objects $container->message = function ($c) { return new Message($c->output, array('with_newline' => $c->with_newline)); }; $container->output = function ($c) { return new $c->output_class(); }; // get the message object $container->message->say('Hello World');
  • 58. spl_object_hash($container->message) !== spl_object_hash($container->message)
  • 59. $container->message = function ($c) { static $object; if (is_null($object)) { $object = new Message($c->output, array('with_newline' => $c->with_newline)); } return $object; };
  • 60. spl_object_hash($container->message) === spl_object_hash($container->message)
  • 61. function asShared($callable) { return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); } return $object; }; }
  • 62. $container->message = $container->asShared(function ($c) { return new Message( $c->output, array('with_newline' => $c->with_newline) ); });
  • 63. class DIContainer { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { if (!isset($this->values[$id])) { throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id)); } if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } }
  • 64. class DIContainer { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { if (!isset($this->values[$id])) { throw new InvalidArgumentException(sprintf('Value "%s" is not defined.', $id)); } if (is_callable($this->values[$id])) { return $this->values[$id]($this); } else { return $this->values[$id]; } } function asShared($callable) { return function ($c) use ($callable) { static $object; 40 LOC pour un if (is_null($object)) { $object = $callable($c); co ntainer DI complet } return $object; }; } }
  • 66. Twittee: A Dependency Injection Container in a tweet •  Implementation does not use PHP 5.3 •  Its usage needs PHP 5.3 class Container { protected $s=array(); function __set($k, $c) { $this->s[$k]=$c; } function __get($k) { return $this->s[$k]($this); } } witte e.org t
  • 69. Un objet (sujet) maintient une liste d’observateurs et les informe automatiquement des changements intervenus en appelant une méthode
  • 70. Un dispatcher est un point central permettant de gérer les connections entre les sujets et les observateurs
  • 71. // an anonymous listener $listener = function ($parameters) { echo "Hello {$parameters['name']}n"; }; // register the listener with the dispatcher $dispatcher = new EventDispatcher(array( 'foo' => $listener, )); // notify the event somewhere $dispatcher->notify('foo', array('name' => 'Fabien'));
  • 72. class EventDispatcher { function __construct($listeners) { $this->listeners = $listeners; } function notify($name, $parameters = array()) { $this->listeners[$name]($parameters); } }
  • 73. Comment enregistrer plusieurs observateurs ? $listener = new EventListeners( function ($parameters) { echo "Hello {$parameters['name']}?n"; }, function ($parameters) { echo "Hello {$parameters['name']}!n"; } ); $dispatcher = new EventDispatcher(array( 'foo' => $listener )); $dispatcher->notify('foo', array('name' => 'Fabien'));
  • 74. class EventListeners { function __construct() { $this->listeners = func_get_args(); } function __invoke($parameters = array()) { foreach ($this->listeners as $listener) { $listener($parameters); } } }
  • 75. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  • 76. symfony-live.com with Matthew Weier O’Pheinney … with Matthew Weier O'Phinney as a special guest
  • 78. Sensio S.A. 92-98, boulevard Victor Hugo 92 115 Clichy Cedex FRANCE Tél. : +33 1 40 99 80 80 Contact Fabien Potencier fabien.potencier at sensio.com http://www.sensiolabs.com/ http://www.symfony-project.org/ http://fabien.potencier.org/