Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Practical PHP 5.3

12.227 Aufrufe

Veröffentlicht am

PHP 5.3 has many new features that allow very different paradigms of software development, that may be unfamiliar to many PHP developers. If you want to learn more about functional or aspect-oriented programming, or how to organize your PHP libraries according to the new de facto PHP namespacing standard, don't miss this talk.

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Practical PHP 5.3

  1. 1. Practical PHP 5.3 Nate Abele 2.6.2010 IPC Berlin
  2. 2. Me • Former lead developer, CakePHP • Co-founder & current lead developer, Lithium • Developing on 5.3 for ~2 years • Twitter: @nateabele
  3. 3. PHP Renaissance • Long-awaited features finalized and committed • Resurgence of energy and interest in evolving the language • Trunk == iteration on latest stable release
  4. 4. Anyway...
  5. 5. Little Things • Performance • ext/fileinfo • Syntax • ext/sqlite3 • Phar • ext/intl • SPL classes • mysqlnd
  6. 6. Big Things • Late static binding • Namespaces • Lambdas / closures
  7. 7. Late-static binding (LSB) class Base { public static function foo() { $subclass = get_called_class(); // ...do some logic with $subclass... } } class Child extends Base { public static function bar() { return static::foo() + 1; } } class Grandchild extends Child { public static function foo() { $result = parent::foo(); // ...do some logic with $result... return $result; } }
  8. 8. Late-static binding (LSB) • static:: ~= $this-> • get_called_class() - the subclass that invoked the method • parent:: - same idea you’re used to • Always use static:: or parent::, self:: etc. breaks the chain
  9. 9. Late-static binding (LSB) • Attributes still a little “broken” class A { public static $message; } class B extends A {} class C extends A {} B::$message = 'WTF?'; echo C::$message; // echoes 'WTF?'
  10. 10. Late-static binding (LSB) • Attributes still a little “broken” class A { public static $message; } class B extends A {} class C extends A { public static $message = 'Overridden'; } B::$message = 'WTF?'; echo C::$message; // echoes 'Overridden'
  11. 11. Late-static binding (LSB) • Attributes still a little “broken” class A { public static $message; } class B extends A { public static $message = 'Overridden'; } class C extends A { } A::$message = 'WTF?'; echo C::$message; // echoes 'WTF?'
  12. 12. Why? • Properly architect stateless portions of apps • Utility classes • Immutable state
  13. 13. “Dynamic” statics • $foo->$bar() vs. Foo::bar() • $foo = 'Foo'; $bar = 'bar'; $foo::$bar(); • __callStatic()
  14. 14. “Dynamic” statics class Dispatcher { public function run($url) { $parameters = Router::match($url); // ... } }
  15. 15. “Dynamic” statics class Dispatcher { public $router = 'Router'; public function run($url) { $router = $this->router; $parameters = $router::match($url); // ... } }
  16. 16. Namespaces • Finally! • What’s up with the ? • Actually “packages”
  17. 17. Namespaces namespace foobar; class MyClass { // ... } $class = new foobarMyClass(); // -- or -- use foobarMyClass; $class = new MyClass();
  18. 18. Namespace use foobar; $class = new barMyClass(); namespace me; $list = new SplDoublyLinkedList(); namespace me; $list = new SplDoublyLinkedList(); namespace me; $class = 'foobarMyClass'; $object = new $class();
  19. 19. PSR-0 http://groups.google.com/group/php-standards/web/psr-0-final-proposal
  20. 20. PSR-0 • Maps top-level vendor package name to filesystem location • Maps file names 1:1 with class name
  21. 21. PSR-0 • lithiumcoreLibraries => /path/to/classes/lithium/core/Libraries.php • lithiumLibraries => /path/to/classes/lithium/Libraries.php • LithiumCoreLibraries => /path/to/classes/Lithium/Core/Libraries.php • Lithium_Core_Libraries => /path/to/classes/Lithium/Core/Libraries.php
  22. 22. Original (PEAR) Draft • Requires sub-packages • Namespaces must be lower-cased and underscored
  23. 23. Original (PEAR) Draft • LithiumCore: ? • lithiumcore: Obviously a namespace • Sub-packages promote reuse outside vendor libraries
  24. 24. SplClassLoader • Concrete implementation of PSR-0 • PHP version: http://gist.github.com/221634 • C version: http://github.com/metagoto/splclassloader
  25. 25. Intermission
  26. 26. Ternary Shortcut // Old: public function foo($parameter = null) { $parameter = $parameter ? $parameter : $this->_calculateDefault(); // ... } // New: public function foo($parameter = null) { $parameter = $parameter ?: $this->_calculateDefault(); // ... }
  27. 27. Phar • include 'phar:///path/to/file.phar/file.php'; • Redistributable apps • Plugins • Application templates
  28. 28. Phar $archive = new Phar("/path/new_file.phar"); $archive->buildFromDirectory( '/path/to/my/app', '/.(php|htaccess|jpg|png|gif|css|js|ico|json|ini)$/' ); $archive->compress(Phar::GZ);
  29. 29. Lambdas & Closures • Lambda: a function assigned to a variable • Closure: a lambda, but bound to variables in the current scope • This is an extremely big deal
  30. 30. Lambdas & Closures $names = array( 'Nate Abele', 'David Coallier', 'Cap'n Crunch' ); $split = array_map( function($name) { list($first, $last) = explode(' ', $name); return compact('first', 'last'); }, $names ); // Result: array( array('first' => 'Nate', 'last' => 'Abele'), array('first' => 'David', 'last' => 'Coallier'), array('first' => 'Cap'n', 'last' => 'Crunch') )
  31. 31. Lambdas & Closures $names = array('Nate Abele', 'David Coallier', /* ... */); $filter = array('Nate', 'David'); $mapper = function($name) use ($filter) { list($first, $last) = explode(' ', $name); if (!in_array($first, $filter)) { return null; } return compact('first', 'last'); }; $filtered = array_map($mapper, $names);
  32. 32. Lambdas & Closures $findActive = function($object) use (&$findActive) { if ($object->isActive) { return $object; } if ($object->children) { foreach ($object->children as $child) { return $findActive($child); } } };
  33. 33. Lambdas & Closures class SomeWebService { public function call($data) { $request = new HttpRequest(); // Configure $request... $result = $request->send(); // Do some processing... // Update $request for next operation... $final = $request->send(); // Post-process $final to extract some value return $someExtractedValue; } }
  34. 34. Lambdas & Closures class SomeWebService { public function call($data, $pre = null, $post = null) { $request = new HttpRequest(); // ... if ($pre) { $request = $pre($request); } $result = $request->send(); if ($post) { $result = $post($result); } // ... $final = $request->send(); // ... } }
  35. 35. Lambdas & Closures class Database { public $callThisOnEveryRead; public function read($query) { if ($callback = $this->callThisOnEveryRead) { $callback($query); } // ... } }
  36. 36. Lambdas & Closures class Database { public $callThisOnEveryRead; public function read($query) { if ($callback = $this->callThisOnEveryRead) { $result = $callback($query) if ($result !== null) { return $result; } } // ... } }
  37. 37. No $this
  38. 38. Referential Transparency • Only needs parameters to calculate a return value (i.e. no $_*, $this or date(), etc.) • Doesn’t produce any side-effects • No modifications outside current scope • No references • No , , etc. echo headers()
  39. 39. lithiumutilcollectionFilters
  40. 40. Method Filters class Database { public function read($query) { // ... run the query ... return $result; } }
  41. 41. Method Filters class Database { public function read($query) { $method = function() { // ... run the query ... return $result; }; } }
  42. 42. Method Filters class Database { public function read($query) { $method = function($query) { // ... run the query ... return $result; }; return $method($query); } }
  43. 43. Method Filters class Database extends lithiumcoreObject { public function read($query) { $method = function($self, $params) { // ... run the query ... return $result; }; return $this->_filter( __METHOD__, compact('query'), $method ); } }
  44. 44. Method Filters $database = new Database($connectionDetails); $database->applyFilter('read', function($self, $params, $chain) { $key = md5(serialize($params['query'])); if ($result = Cache::read($key)) { return $result; } $result = $chain->next($self, $params, $chain); Cache::write($key, $result); return $result; });
  45. 45. lithiumutilcollectionFilters outer inner read()
  46. 46. AOP in a Nutshell • Obliviousness • Eliminates boilerplate code per class relationship • Centralized configuration of concerns
  47. 47. Thanks! • nate.abele@gmail.com • @nateabele • http://lithify.me/

×