Practical PHP 5.3
Nate Abele   2.6.2010   IPC   Berlin
Me

• Former lead developer, CakePHP
• Co-founder & current lead developer,
  Lithium

• Developing on 5.3 for ~2 years
• ...
PHP Renaissance

• Long-awaited features finalized and
   committed

• Resurgence of energy and interest in
   evolving the...
Anyway...
Little Things

• Performance   • ext/fileinfo
• Syntax        • ext/sqlite3
• Phar          • ext/intl
• SPL classes   • my...
Big Things

• Late static binding
• Namespaces
• Lambdas / closures
Late-static binding (LSB)
class Base {
    public static function foo() {
        $subclass = get_called_class();
        ...
Late-static binding (LSB)
•   static::   ~= $this->

•   get_called_class() -    the subclass that
    invoked the method
...
Late-static binding (LSB)

• Attributes still a little “broken”
   class A {
       public static $message;
   }
   class ...
Late-static binding (LSB)

• Attributes still a little “broken”
   class A {
       public static   $message;
   }
   clas...
Late-static binding (LSB)

• Attributes still a little “broken”
   class A {
       public static   $message;
   }
   clas...
Why?

• Properly architect stateless portions of
   apps

• Utility classes
• Immutable state
“Dynamic” statics

•   $foo->$bar()   vs. Foo::bar()

•   $foo = 'Foo';
    $bar = 'bar';
    $foo::$bar();


•   __callSt...
“Dynamic” statics

class Dispatcher {

    public function run($url) {
        $parameters = Router::match($url);
        ...
“Dynamic” statics
class Dispatcher {

    public $router = 'Router';

    public function run($url) {
        $router = $t...
Namespaces

• Finally!
• What’s up with the  ?
• Actually “packages”
Namespaces
namespace foobar;

class MyClass {
    // ...
}


$class = new foobarMyClass();

// -- or --

use foobarMyClass...
Namespace
use foobar;
$class = new barMyClass();

namespace me;
$list = new SplDoublyLinkedList();


namespace me;
$list =...
PSR-0
http://groups.google.com/group/php-standards/web/psr-0-final-proposal
PSR-0


• Maps top-level vendor package name to
  filesystem location

• Maps file names 1:1 with class name
PSR-0
•   lithiumcoreLibraries      =>
    /path/to/classes/lithium/core/Libraries.php


•   lithiumLibraries     =>
    /...
Original (PEAR) Draft


• Requires sub-packages
• Namespaces must be lower-cased and
  underscored
Original (PEAR) Draft

• LithiumCore: ?
• lithiumcore: Obviously a namespace
• Sub-packages promote reuse outside
  vendor...
SplClassLoader

• Concrete implementation of PSR-0
• PHP version:
  http://gist.github.com/221634

• C version:
  http://g...
Intermission
Ternary Shortcut

// Old:
public function foo($parameter = null) {
    $parameter = $parameter ? $parameter : $this->_calc...
Phar

•  include 'phar:///path/to/file.phar/file.php';


• Redistributable apps
• Plugins
• Application templates
Phar

$archive = new Phar("/path/new_file.phar");

$archive->buildFromDirectory(
    '/path/to/my/app',
    '/.(php|htacce...
Lambdas & Closures

• Lambda: a function assigned to a variable
• Closure: a lambda, but bound to variables
   in the curr...
Lambdas & Closures
$names = array(
   'Nate Abele', 'David Coallier', 'Cap'n Crunch'
);
$split = array_map(
    function($...
Lambdas & Closures
$names = array('Nate Abele', 'David Coallier', /* ... */);
$filter = array('Nate', 'David');

$mapper =...
Lambdas & Closures
$findActive = function($object) use (&$findActive) {
    if ($object->isActive) {
        return $objec...
Lambdas & Closures
class SomeWebService {

    public function call($data) {
        $request = new HttpRequest();
       ...
Lambdas & Closures
class SomeWebService {

    public function call($data, $pre = null, $post = null) {
        $request =...
Lambdas & Closures
class Database {

    public $callThisOnEveryRead;

    public function read($query) {
        if ($cal...
Lambdas & Closures
class Database {

    public $callThisOnEveryRead;

    public function read($query) {
        if ($cal...
No $this
Referential Transparency
• Only needs parameters to calculate a
  return value (i.e. no $_*,   $this   or   date(),
  etc....
lithiumutilcollectionFilters
Method Filters

class Database {

    public function read($query) {
        // ... run the query ...
        return $resu...
Method Filters

class Database {

    public function read($query) {
        $method = function() {
            // ... run...
Method Filters

class Database {

    public function read($query) {
        $method = function($query) {
            // ....
Method Filters

class Database extends lithiumcoreObject {

    public function read($query) {
        $method = function(...
Method Filters
$database = new Database($connectionDetails);

$database->applyFilter('read', function($self, $params, $cha...
lithiumutilcollectionFilters



             outer


             inner


            read()
AOP in a Nutshell

• Obliviousness
• Eliminates boilerplate code per class
   relationship

• Centralized configuration of ...
Thanks!

• nate.abele@gmail.com
• @nateabele
• http://lithify.me/
Practical PHP 5.3
Nächste SlideShare
Wird geladen in …5
×

Practical PHP 5.3

12.009 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
0 Kommentare
11 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
12.009
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
874
Aktionen
Geteilt
0
Downloads
121
Kommentare
0
Gefällt mir
11
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

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/

×