PHP 5.3 in practice
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

PHP 5.3 in practice

on

  • 11,922 views

 

Statistics

Views

Total Views
11,922
Views on SlideShare
11,764
Embed Views
158

Actions

Likes
16
Downloads
245
Comments
0

11 Embeds 158

http://coderwall.com 65
http://www.slideshare.net 55
https://intranet.netformic.net 14
http://www.westworld.be 14
http://paper.li 3
http://www.linkedin.com 2
http://www.sfexception.com 1
http://us-w1.rockmelt.com 1
http://srukwebdev01.totemic.local 1
http://www.techgig.com 1
http://symfony2developer.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

PHP 5.3 in practice Presentation Transcript

  • 1. PHP 5.3 in practice Fabien Potencier PHP 5.3 in practice – Fabien Potencier
  • 2. Fabien Potencier •  Serial entrepreneur and developer by passion •  Founder of Sensio (in 1998) –  A services and consulting company specialized in Web technologies and Internet marketing (France and USA) –  70 people –  Open-Source specialists –  Big corporate customers –  Consulting, training, development, web design, … and more –  Sponsor of a lot of Open-Source projects like symfony and Doctrine PHP 5.3 in practice – Fabien Potencier
  • 3. Fabien Potencier •  Creator and lead developer of symfony… •  and creator and lead developer of some more OSS: –  Symfony components –  Swift Mailer : Powerful component based mailing library for PHP –  Twig : Fexible, fast, and secure template language for PHP –  Pirum : Simple PEAR Channel Server Manager –  Sismo : PHP continuous integration server –  Lime : Easy to use unit testing library for PHP –  Twitto : A web framework in a tweet –  Twittee : A Dependency Injection injector in a tweet –  Pimple : A small PHP 5.3 dependency injection injector PHP 5.3 in practice – Fabien Potencier
  • 4. Fabien Potencier •  Read my technical blog: http://fabien.potencier.org/ •  Follow me on Twitter: @fabpot •  Fork my code on Github: http://github.com/fabpot/ PHP 5.3 in practice – Fabien Potencier
  • 5. Migrating to PHP 5.3 … for technical reasons PHP 5.3 in practice – Fabien Potencier
  • 6. Migrating to PHP 5.3? •  Why? – Much faster – Less memory •  When? – PHP 5.3.1 is available – PHP 5.3.2 is about to be released and stable – Migration is simple enough PHP 5.3 in practice – Fabien Potencier
  • 7. Migrating to PHP 5.3 … for speed PHP 5.3 in practice – Fabien Potencier
  • 8. Dmitry Stogov did some benchmarks for popular PHP applications Drupal 20% faster Typo3 30% faster Wordpress 15% faster Xoops 10% faster http://news.php.net/php.internals/36484 PHP 5.3 in practice – Fabien Potencier
  • 9. Doctrine 1.X and 2.0 Faster with PHP 5.3 and less memory consumption 30% less memory 20% faster PHP 5.3 in practice – Fabien Potencier
  • 10. symfony 1 -47% symfony project running on PHP 5.2 vs PHP 5.3 profiled with XHPROF (run 4aeeb7d54b732 is PHP 5.3) PHP 5.3 in practice – Fabien Potencier
  • 11. Migrating to PHP 5.3 … for the ecosystem PHP 5.3 in practice – Fabien Potencier
  • 12. Second generation of PHP frameworks •  The next major versions of the most popular frameworks and libraries will use PHP 5.3 –  Symfony 2.0 –  Doctrine 2.0 Late 2010 –  Zend Framework 2.0 •  Better interoperability between these libraries, thanks to namespaces PHP 5.3 in practice – Fabien Potencier
  • 13. Namespaces and Symfony 2 SymfonyComponents SymfonyFoundation SymfonyFramework SymfonyComponentsEventDispatcherEvent SymfonyFoundationUniversalClassLoader PHP 5.3 in practice – Fabien Potencier
  • 14. SymfonyComponentsEventDispatcherEvent vs sfEvent Class names are NOT shorter PHP 5.3 in practice – Fabien Potencier
  • 15. Namespaces and Symfony 2 require __DIR__.'/lib/Symfony/Core/ClassLoader.php'; use SymfonyFoundationClassLoader; use SymfonyComponentsEventDispatcherEvent; $loader = new ClassLoader('Symfony', __DIR__.'/lib'); $loader->register(); $event = new Event(); PHP 5.3 in practice – Fabien Potencier
  • 16. Namespaces and Symfony 2 require __DIR__.'/lib/Symfony/Core/ClassLoader.php'; use SymfonyFoundationClassLoader; use SymfonyComponentsEventDispatcherEvent; $loader = new ClassLoader('Symfony', __DIR__.'/lib'); $loader->register(); $event = new Event(); PHP 5.3 in practice – Fabien Potencier
  • 17. 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/psr-0-final-proposal PHP 5.3 in practice – Fabien Potencier
  • 18. Why? •  Libraries following the specification are interoperable •  For instance, if you use Symfony 2.0, Doctrine 2.0, and Zend Framework 2.0 in the same project –  They can all share the same autoloader –  Symfony 2.0 provides an enhanced autoloader (with PEAR support) –  A native C extension has been created PHP 5.3 in practice – Fabien Potencier
  • 19. Let’s dive into PHP 5.3 PHP 5.3 in practice – Fabien Potencier
  • 20. PHP 5.3 •  A lot of changes –  Convenient changes: __DIR__, ?:, NOWDOC, … –  New features: i18n, SPL, Date management, mysqlnd, … –  Language enhancements: namespaces, anonymous functions, closures, late static binding, phar, Windows support, … PHP 5.3 in practice – Fabien Potencier
  • 21. PHP 5.3 How does it change the implementation of some well-known Design Pattern? PHP 5.3 in practice – Fabien Potencier
  • 22. PHP 5.3 … and the Singleton PHP 5.3 in practice – Fabien Potencier
  • 23. The Singleton may cause serious damage to your code PHP 5.3 in practice – Fabien Potencier
  • 24. History of the Singleton PHP 5.3 in practice – Fabien Potencier
  • 25. The Singleton in PHP 4 class Singleton { function &getInstance() { static $instance; if (!$instance) { $instance = new Singleton(); } } return $instance; You can still } ins tantiate the class $obj =& Singleton::getInstance(); directly PHP 5.3 in practice – Fabien Potencier
  • 26. The Singleton in 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; do not forget to } } final private function __clone() {} ove rride __clone() $obj = Singleton::getInstance(); PHP 5.3 in practice – Fabien Potencier
  • 27. The Singleton in 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() {} } PHP 5.3 in practice – Fabien Potencier
  • 28. The Singleton in PHP 5.3 class Foo extends Singleton {} class Bar extends Singleton {} $a = Foo::getInstance(); $b = Bar::getInstance(); PHP 5.3 in practice – Fabien Potencier
  • 29. PHP 5.3 …Late Static Binding The ORM problem PHP 5.3 in practice – Fabien Potencier
  • 30. class Model { static public function getMe() { return __CLASS__; } } class Article extends Model {} echo Article::getMe(); PHP 5.3 in practice – Fabien Potencier
  • 31. <?php class Model { static public function getMe() { return get_called_class(); as of PHP 5.3 } } class Article extends Model {} echo Article::getMe(); PHP 5.3 in practice – Fabien Potencier
  • 32. class Model { static public function findByPk($id) { $table = strtolower(get_called_class()); return $db->get( sprintf('SELECT * FROM %s WHERE id = %d', $table, $id) ); } } class Article extends Model {} $article = Article::findByPk(1); PHP 5.3 in practice – Fabien Potencier
  • 33. class Model { static public function __callStatic($method, $arguments) { $table = strtolower(get_called_class()); $column = strtolower(substr($method, 6)); $value = $arguments[0]; $sql = sprintf('SELECT * FROM %s WHERE %s = ?', $table, $column); return $db->get($sql, $value); } } class Article extends Model {} $article = Article::findByTitle('foo'); PHP 5.3 in practice – Fabien Potencier
  • 34. PHP 5.3 …interlude Anonymous functions Lambdas PHP 5.3 in practice – Fabien Potencier
  • 35. An anonymous function is a function defined on the fly (no name) function () { echo 'Hello world!'; }; PHP 5.3 in practice – Fabien Potencier
  • 36. Can be stored in a variable $hello = function () { echo 'Hello world!'; }; PHP 5.3 in practice – Fabien Potencier
  • 37. … to be used later on $hello(); call_user_func($hello); PHP 5.3 in practice – Fabien Potencier
  • 38. … or can be passed as a function argument function foo(Closure $func) { $func(); } foo($hello); PHP 5.3 in practice – Fabien Potencier
  • 39. Fonctions anonymes Can take arguments $hello = function ($name) { echo 'Hello '.$name; }; $hello('Fabien'); call_user_func($hello, 'Fabien'); PHP 5.3 in practice – Fabien Potencier
  • 40. Fonctions anonymes function foo(Closure $func, $name) { $func($name); } foo($hello, 'Fabien'); PHP 5.3 in practice – Fabien Potencier
  • 41. When is it useful? PHP 5.3 in practice – Fabien Potencier
  • 42. array_* Greatly simplify usage of some array_* functions array_map() array_reduce() array_filter() PHP 5.3 in practice – Fabien Potencier
  • 43. class Article { public function __construct($title) { $this->title = $title; } public function getTitle() { return $this->title; } } PHP 5.3 in practice – Fabien Potencier
  • 44. How to get an array of all article titles? $articles = array( new Article('PHP UK - part 1'), new Article('PHP UK - part 2'), new Article('See you next year!'), ); PHP 5.3 in practice – Fabien Potencier
  • 45. $titles = array(); foreach ($articles as $article) { $titles[] = $article->getTitle(); } PHP 5.3 in practice – Fabien Potencier
  • 46. $titles = array_map( create_function('$article', 'return $article->getTitle();'), $articles ); PHP 5.3 in practice – Fabien Potencier
  • 47. $titles = array_map( function ($article) { return $article->getTitle(); }, $articles ); PHP 5.3 in practice – Fabien Potencier
  • 48. $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 memory speed PHP 5.3 in practice – Fabien Potencier
  • 49. $mapper = function ($article) { return $article->getTitle(); }; $titles = array_map($mapper, $articles); $mapper = function ($article) { return $article->getAuthor(); }; $authors = array_map($mapper, $articles); PHP 5.3 in practice – Fabien Potencier
  • 50. A closure is a lambda that remembers the context of its creation… PHP 5.3 in practice – Fabien Potencier
  • 51. $mapper = function ($method) { return function ($article) use($method) { return $article->$method(); }; }; PHP 5.3 in practice – Fabien Potencier
  • 52. $method = 'getTitle'; $mapper = function ($article) use($method) { return $article->$method(); }; $method = 'getAuthor'; $titles = array_map($mapper, $articles); PHP 5.3 in practice – Fabien Potencier
  • 53. $titleMapper = $mapper('getTitle'); $titles = array_map($titleMapper, $articles); $authorMapper = $mapper('getAuthor'); $authors = array_map($authorMapper, $articles); PHP 5.3 in practice – Fabien Potencier
  • 54. $titles = array_map($mapper('getTitle'), $articles); $authors = array_map($mapper('getAuthor'), $articles); PHP 5.3 in practice – Fabien Potencier
  • 55. Dependency Injector PHP 5.3 in practice – Fabien Potencier
  • 56. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » http://www.picoinjector.org/injection.html PHP 5.3 in practice – Fabien Potencier
  • 57. Dependency Injection A real world « web » example PHP 5.3 in practice – Fabien Potencier
  • 58. In most web applications, you need to manage the user preferences –  The user language –  Whether the user is authenticated or not –  The user credentials –  … PHP 5.3 in practice – Fabien Potencier
  • 59. This can be done with a User object –  setLanguage(), getLanguage() –  setAuthenticated(), isAuthenticated() –  addCredential(), hasCredential() –  ... PHP 5.3 in practice – Fabien Potencier
  • 60. The User information need to be persisted between HTTP requests We use the PHP session for the Storage PHP 5.3 in practice – Fabien Potencier
  • 61. class SessionStorage { function __construct($cookieName = 'PHP_SESS_ID') { session_name($cookieName); session_start(); } function set($key, $value) { $_SESSION[$key] = $value; } // ... } PHP 5.3 in practice – Fabien Potencier
  • 62. class User { protected $storage; function __construct() Very hard to { customize $this->storage = new SessionStorage(); } function setLanguage($language) { $this->storage->set('language', $language); } // ... } Very easy to use $user = new User(); PHP 5.3 in practice – Fabien Potencier
  • 63. class User { protected $storage; Very easy to customize function __construct($storage) { $this->storage = $storage; } } $storage = new SessionStorage(); $user = new User($storage); Slightly more difficult to use PHP 5.3 in practice – Fabien Potencier
  • 64. That’s Dependency Injection Nothing more PHP 5.3 in practice – Fabien Potencier
  • 65. Instead of harcoding the Storage dependency inside the User class constructor Inject the Storage dependency in the User object PHP 5.3 in practice – Fabien Potencier
  • 66. A Dependency Injector Describes objects and their dependencies Instantiates and configures objects on-demand PHP 5.3 in practice – Fabien Potencier
  • 67. An injector SHOULD be able to manage ANY PHP object (POPO) The objects MUST not know that they are managed by the injector PHP 5.3 in practice – Fabien Potencier
  • 68. •  Parameters –  The SessionStorage implementation we want to use (the class name) –  The session name •  Objects –  SessionStorage –  User •  Dependencies –  User depends on a SessionStorage implementation PHP 5.3 in practice – Fabien Potencier
  • 69. Let’s build a simple injector with PHP 5.3 PHP 5.3 in practice – Fabien Potencier
  • 70. Dependency Injector Managing parameters PHP 5.3 in practice – Fabien Potencier
  • 71. class Injector { protected $parameters = array(); public function setParameter($key, $value) { $this->parameters[$key] = $value; } public function getParameter($key) { return $this->parameters[$key]; } } PHP 5.3 in practice – Fabien Potencier
  • 72. Decoupling $injector = new Injector(); Customization $injector->setParameter('session_name', 'SESSION_ID'); $injector->setParameter('storage_class', 'SessionStorage'); $class = $injector->getParameter('storage_class'); $sessionStorage = new $class($injector->getParameter('session_name')); $user = new User($sessionStorage); Objects creation PHP 5.3 in practice – Fabien Potencier
  • 73. class Injector Using PHP { magic methods protected $parameters = array(); public function __set($key, $value) { $this->parameters[$key] = $value; } public function __get($key) { return $this->parameters[$key]; } } PHP 5.3 in practice – Fabien Potencier
  • 74. Interface is cleaner $injector = new Injector(); $injector->session_name = 'SESSION_ID'; $injector->storage_class = 'SessionStorage'; $sessionStorage = new $injector->storage_class($injector->session_name); $user = new User($sessionStorage); PHP 5.3 in practice – Fabien Potencier
  • 75. Dependency Injector Managing objects PHP 5.3 in practice – Fabien Potencier
  • 76. We need a way to describe how to create objects, without actually instantiating anything! Anonymous functions to the rescue! PHP 5.3 in practice – Fabien Potencier
  • 77. class Injector { protected $parameters = array(); protected $objects = array(); public function __set($key, $value) { $this->parameters[$key] = $value; } public function __get($key) Store a lambda { return $this->parameters[$key]; able to create the object on-demand } public function setService($key, Closure $service) { $this->objects[$key] = $service; } public function getService($key) Ask the closure to create { return $this->objects[$key]($this); th e object and pass the } } current injector PHP 5.3 in practice – Fabien Potencier
  • 78. $injector = new Injector(); $injector->session_name = 'SESSION_ID'; Description $injector->storage_class = 'SessionStorage'; $injector->setService('user', function ($c) { return new User($c->getService('storage')); }); $injector->setService('storage', function ($c) { return new $c->storage_class($c->session_name); }); Creating the User is now as easy as before $user = $injector->getService('user'); PHP 5.3 in practice – Fabien Potencier
  • 79. class Injector { protected $values = array(); Simplify the code 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]; } } } PHP 5.3 in practice – Fabien Potencier
  • 80. $injector = new Injector(); Unified interface $injector->session_name = 'SESSION_ID'; $injector->storage_class = 'SessionStorage'; $injector->user = function ($c) { return new User($c->storage); }; $injector->storage = function ($c) { return new $c->storage_class($c->session_name); }; $user = $injector->user; PHP 5.3 in practice – Fabien Potencier
  • 81. Dependency Injector Scope PHP 5.3 in practice – Fabien Potencier
  • 82. For some objects, like the user, the injector must always return the same instance PHP 5.3 in practice – Fabien Potencier
  • 83. spl_object_hash($injector->user) !== spl_object_hash($injector->user) PHP 5.3 in practice – Fabien Potencier
  • 84. $injector->user = function ($c) { static $user; if (is_null($user)) { $user = new User($c->storage); } return $user; }; PHP 5.3 in practice – Fabien Potencier
  • 85. spl_object_hash($injector->user) === spl_object_hash($injector->user) PHP 5.3 in practice – Fabien Potencier
  • 86. $injector->user = $injector->asShared(function ($c) { return new User($c->storage); }); PHP 5.3 in practice – Fabien Potencier
  • 87. function asShared(Closure $lambda) { return function ($injector) use ($lambda) { static $object; if (is_null($object)) { $object = $lambda($injector); } return $object; }; } PHP 5.3 in practice – Fabien Potencier
  • 88. class Injector { protected $values = array(); function __set($id, $value) { $this->values[$id] = $value; } function __get($id) { Error management 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]; } } } PHP 5.3 in practice – Fabien Potencier
  • 89. class injector { 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) { 40 LOC for a fully- return function ($c) use ($callable) { static $object; if (is_null($object)) { $object = $callable($c); featured injector } return $object; }; } } PHP 5.3 in practice – Fabien Potencier
  • 90. I’m NOT advocating the usage of lambdas everywhere This presentation was about showing how they work on practical examples PHP 5.3 in practice – Fabien Potencier
  • 91. Questions? PHP 5.3 in practice – Fabien Potencier
  • 92. 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/ PHP 5.3 in practice – Fabien Potencier