Jouons avec PHP 5.3

Fabien Potencier
Fabien Potencier
•  Serial entrepreneur et développeur par passion
•  Fondateur de Sensio (1998)
   –  Société de conseil
...
Fabien Potencier

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

•  Sur Twitter : http://www.twitter.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 ...
PHP 5.3
Beaucoup plus rapide ?
Dmitry Stogov a fait quelques tests de performance
                     pour des applications PHP connues

               ...
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%


...
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...
PHP 5.3 technical interoperability standards

           « … describes the mandatory requirements
                     tha...
Pourquoi ?
•  Les bibliothèques respectant cette spécification simple
   –  seront techniquement 100% interopérable
   –  p...
Les namespaces dans Symfony 2
SymfonyComponents
SymfonyFoundation
SymfonyFramework

SymfonyComponentsEventDispatcherEvent
...
SymfonyComponentsEventDispatcherEvent


                   vs


                sfEvent

                           L e no...
Les namespaces dans Symfony 2
$classLoader = new ClassLoader('Symfony', __DIR__.'/lib');
$classLoader->register();

$conta...
Les namespaces dans Symfony 2
require __DIR__.'/lib/Symfony/Core/ClassLoader.php';

use SymfonyFoundationClassLoader;
use ...
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 ent...
PHP 5, une rupture technologique
•  Arrivée de frameworks matures : symfony, Zend Framework, CakePHP,
   Prado, …
•  Profe...
L’adoption de PHP 5.3 devrait être rapide dans les entreprises
   –  Migration facile
   –  Support Windows amélioré (rapi...
PHP 5.3 dans les entreprises en 2010/2011

•  Une évolution technologique qui va permettre de continuer le
   changement d...
PHP 5.3
Parlons technique…
PHP 5.3
•  Beaucoup de nouveautés

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

   –  Fonctionnelles : i18n, SPL, gestion d...
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 &getInsta...
Le Singleton en PHP 5.0/5.1/5.2
class Singleton
{
  static private $instance;

    private function __construct() {}

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

    final private function __co...
Le Singleton en PHP 5.3

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

$a = Foo::getInstance();
$b = Bar:...
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)

func...
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...
Fonctions anonymes
$hello = function ($name) { echo 'Hello '.$name; };

$hello('Fabien');

call_user_func($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)
  {
    $t...
$titles = array();
foreach ($articles as $article)
{
  $titles[] = $article->getTitle();
}

                              ...
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 = function ($method)
{
   return function ($article) use($method)
   {
      return $article->$method();
   };
};
...
Questions ?
Injection de Dépendance
« Dependency Injection is where components
 are given their dependencies through their
constructors, methods, or directly ...
class Message
{
  public function __construct(array $options)
  {
    $this->output = new FancyOutput();

        // ...
 ...
class Message
{
  public function __construct(OutputInterface $output, array $options)
  {
    $this->output = $output;
  ...
interface OutputInterface
{
  public function render($msg);
}


class Output implements OutputInterface
{
  public functio...
$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] = $valu...
// define the parameters
$container->output_class = 'FancyOutput';
$container->with_newline = true;

// defined the object...
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,...
spl_object_hash($container->message)



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

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

    function __set($id, $value)
    {
      $this->values[$id] = $valu...
class DIContainer
{
  protected $values = array();

    function __set($id, $value)
    {
      $this->values[$id] = $valu...
plus d’infos…

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



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


c...
Questions ?
Observateur
Un objet (sujet)
maintient une liste d’observateurs
et les informe automatiquement
  des changements intervenus
    en app...
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 th...
class EventDispatcher
{
  function __construct($listeners)
  {
    $this->listeners = $listeners;
  }

    function notify...
Comment enregistrer plusieurs observateurs ?



$listener = new EventListeners(
   function ($parameters) { echo "Hello {$...
class EventListeners
{
  function __construct()
  {
    $this->listeners = func_get_args();
  }

    function __invoke($pa...
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...
Playing With PHP 5.3
Upcoming SlideShare
Loading in …5
×

Playing With PHP 5.3

7,420 views

Published on

Published in: Technology, Business
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
7,420
On SlideShare
0
From Embeds
0
Number of Embeds
1,055
Actions
Shares
0
Downloads
127
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Playing With PHP 5.3

  1. 1. Jouons avec PHP 5.3 Fabien Potencier
  2. 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. 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. 4. Migrer vers PHP 5.3 Des raisons techniques
  5. 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
  6. 6. PHP 5.3 Beaucoup plus rapide ?
  7. 7. 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
  8. 8. Doctrine 1.X and 2.0 Significativement plus rapide avec PHP 5.3 30% de mémoire en moins 20% plus rapide
  9. 9. symfony 1.X -47% symfony project running on PHP 5.2 vs PHP 5.3 profiled with XHPROF (run 4aeeb7d54b732 is PHP 5.3)
  10. 10. Migrer vers PHP 5.3 Des raisons fonctionnelles
  11. 11. 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
  12. 12. 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
  13. 13. 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
  14. 14. Les namespaces dans Symfony 2 SymfonyComponents SymfonyFoundation SymfonyFramework SymfonyComponentsEventDispatcherEvent SymfonyFoundationClassLoader
  15. 15. SymfonyComponentsEventDispatcherEvent vs sfEvent L e nom des classes n’es t pas plus court !
  16. 16. 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();
  17. 17. 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
  18. 18. PHP 5.3 L’apport pour les entreprises
  19. 19. 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
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. PHP 5.3 Parlons technique…
  24. 24. 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, …
  25. 25. PHP 5.3 Le singleton
  26. 26. Le singleton nuit gravement à la santé de votre code
  27. 27. sfContext dans symfony est “juste” l’exception qui confirme la règle ;)
  28. 28. Le Singleton à travers les âges
  29. 29. 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();
  30. 30. 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();
  31. 31. 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() {} }
  32. 32. Le Singleton en PHP 5.3 class Foo extends Singleton {} class Bar extends Singleton {} $a = Foo::getInstance(); $b = Bar::getInstance();
  33. 33. Late Static Binding __callStatic() User::find(1) User::findByUsername('fabien');
  34. 34. Fonctions anonymes
  35. 35. Fonctions Anonymes Une fonction anonyme est une fonction déclarée à la volée (sans nom) function () { echo 'Hello world!'; };
  36. 36. Fonctions Anonymes Pour être affectée à une variable $hello = function () { echo 'Hello world!'; };
  37. 37. Fonctions Anonymes Puis être utilisée $hello(); call_user_func($hello);
  38. 38. Fonctions Anonymes et/ou être passé en argument d’une fonction function foo(Closure $func) { $func(); } foo($hello);
  39. 39. 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');
  40. 40. Que faire avec des fonctions anonymes ?
  41. 41. array_* Simplification de l’usage de array_map() array_reduce() array_filter()
  42. 42. 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 !'), );
  43. 43. $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é
  44. 44. Une closure est une fonction anonyme qui se souvient du contexte dans laquelle elle a été crée…
  45. 45. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $titles = array_map($mapper, $articles);
  46. 46. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; }; $titles = array_map($mapper('getTitle'), $articles);
  47. 47. Questions ?
  48. 48. Injection de Dépendance
  49. 49. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » http://www.picocontainer.org/injection.html
  50. 50. class Message { public function __construct(array $options) { $this->output = new FancyOutput(); // ... } // ... } Impossible de changer la classe FancyOutput par une autre
  51. 51. 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" : '')); } }
  52. 52. 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); } }
  53. 53. $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');
  54. 54. Un container DI permet de décrire les objets et leurs relations de les configurer de les créer
  55. 55. 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]; } } }
  56. 56. // 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');
  57. 57. spl_object_hash($container->message) !== spl_object_hash($container->message)
  58. 58. $container->message = function ($c) { static $object; if (is_null($object)) { $object = new Message($c->output, array('with_newline' => $c->with_newline)); } return $object; };
  59. 59. spl_object_hash($container->message) === spl_object_hash($container->message)
  60. 60. function asShared($callable) { return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); } return $object; }; }
  61. 61. $container->message = $container->asShared(function ($c) { return new Message( $c->output, array('with_newline' => $c->with_newline) ); });
  62. 62. 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]; } } }
  63. 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]; } } 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; }; } }
  64. 64. 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/
  65. 65. 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
  66. 66. Questions ?
  67. 67. Observateur
  68. 68. Un objet (sujet) maintient une liste d’observateurs et les informe automatiquement des changements intervenus en appelant une méthode
  69. 69. Un dispatcher est un point central permettant de gérer les connections entre les sujets et les observateurs
  70. 70. // 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'));
  71. 71. class EventDispatcher { function __construct($listeners) { $this->listeners = $listeners; } function notify($name, $parameters = array()) { $this->listeners[$name]($parameters); } }
  72. 72. 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'));
  73. 73. class EventListeners { function __construct() { $this->listeners = func_get_args(); } function __invoke($parameters = array()) { foreach ($this->listeners as $listener) { $listener($parameters); } } }
  74. 74. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  75. 75. symfony-live.com with Matthew Weier O’Pheinney … with Matthew Weier O'Phinney as a special guest
  76. 76. Questions?
  77. 77. 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/

×