Your SlideShare is downloading. ×

Playing With PHP 5.3

6,726

Published on

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

No Downloads
Views
Total Views
6,726
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
127
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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
  • 6. PHP 5.3 Beaucoup plus rapide ?
  • 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. Doctrine 1.X and 2.0 Significativement plus rapide avec PHP 5.3 30% de mémoire en moins 20% plus rapide
  • 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. Migrer vers PHP 5.3 Des raisons fonctionnelles
  • 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. 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. 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. Les namespaces dans Symfony 2 SymfonyComponents SymfonyFoundation SymfonyFramework SymfonyComponentsEventDispatcherEvent SymfonyFoundationClassLoader
  • 15. SymfonyComponentsEventDispatcherEvent vs sfEvent L e nom des classes n’es t pas plus court !
  • 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. 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. PHP 5.3 L’apport pour les entreprises
  • 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. 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. 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. 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. PHP 5.3 Parlons technique…
  • 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. PHP 5.3 Le singleton
  • 26. Le singleton nuit gravement à la santé de votre code
  • 27. sfContext dans symfony est “juste” l’exception qui confirme la règle ;)
  • 28. Le Singleton à travers les âges
  • 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. 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. 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. Le Singleton en PHP 5.3 class Foo extends Singleton {} class Bar extends Singleton {} $a = Foo::getInstance(); $b = Bar::getInstance();
  • 33. Late Static Binding __callStatic() User::find(1) User::findByUsername('fabien');
  • 34. Fonctions anonymes
  • 35. Fonctions Anonymes Une fonction anonyme est une fonction déclarée à la volée (sans nom) function () { echo 'Hello world!'; };
  • 36. Fonctions Anonymes Pour être affectée à une variable $hello = function () { echo 'Hello world!'; };
  • 37. Fonctions Anonymes Puis être utilisée $hello(); call_user_func($hello);
  • 38. Fonctions Anonymes et/ou être passé en argument d’une fonction function foo(Closure $func) { $func(); } foo($hello);
  • 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. Que faire avec des fonctions anonymes ?
  • 41. array_* Simplification de l’usage de array_map() array_reduce() array_filter()
  • 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. $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. Une closure est une fonction anonyme qui se souvient du contexte dans laquelle elle a été crée…
  • 45. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $titles = array_map($mapper, $articles);
  • 46. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; }; $titles = array_map($mapper('getTitle'), $articles);
  • 47. Questions ?
  • 48. Injection de Dépendance
  • 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. class Message { public function __construct(array $options) { $this->output = new FancyOutput(); // ... } // ... } Impossible de changer la classe FancyOutput par une autre
  • 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. 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. $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');
  • 54. Un container DI permet de décrire les objets et leurs relations de les configurer de les créer
  • 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. // 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. spl_object_hash($container->message) !== spl_object_hash($container->message)
  • 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. spl_object_hash($container->message) === spl_object_hash($container->message)
  • 60. function asShared($callable) { return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); } return $object; }; }
  • 61. $container->message = $container->asShared(function ($c) { return new Message( $c->output, array('with_newline' => $c->with_newline) ); });
  • 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. 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. 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. 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. Questions ?
  • 67. Observateur
  • 68. Un objet (sujet) maintient une liste d’observateurs et les informe automatiquement des changements intervenus en appelant une méthode
  • 69. Un dispatcher est un point central permettant de gérer les connections entre les sujets et les observateurs
  • 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. class EventDispatcher { function __construct($listeners) { $this->listeners = $listeners; } function notify($name, $parameters = array()) { $this->listeners[$name]($parameters); } }
  • 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. class EventListeners { function __construct() { $this->listeners = func_get_args(); } function __invoke($parameters = array()) { foreach ($this->listeners as $listener) { $listener($parameters); } } }
  • 74. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  • 75. symfony-live.com with Matthew Weier O’Pheinney … with Matthew Weier O'Phinney as a special guest
  • 76. Questions?
  • 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/

×