SlideShare une entreprise Scribd logo
1  sur  48
Télécharger pour lire hors ligne
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
• Twitter: @nateabele
PHP Renaissance

• Long-awaited features finalized and
   committed

• Resurgence of energy and interest in
   evolving the language

• Trunk == iteration on latest stable release
Anyway...
Little Things

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

• Late static binding
• Namespaces
• Lambdas / closures
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;
    }
}
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
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?'
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'
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?'
Why?

• Properly architect stateless portions of
   apps

• Utility classes
• Immutable state
“Dynamic” statics

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

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


•   __callStatic()
“Dynamic” statics

class Dispatcher {

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

    public $router = 'Router';

    public function run($url) {
        $router = $this->router;
        $parameters = $router::match($url);
        // ...
    }
}
Namespaces

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

class MyClass {
    // ...
}


$class = new foobarMyClass();

// -- or --

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

namespace me;
$list = new SplDoublyLinkedList();


namespace me;
$list = new SplDoublyLinkedList();

namespace me;
$class = 'foobarMyClass';
$object = new $class();
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     =>
    /path/to/classes/lithium/Libraries.php


•   LithiumCoreLibraries      =>
    /path/to/classes/Lithium/Core/Libraries.php


•   Lithium_Core_Libraries      =>
    /path/to/classes/Lithium/Core/Libraries.php
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 libraries
SplClassLoader

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

• C version:
  http://github.com/metagoto/splclassloader
Intermission
Ternary Shortcut

// Old:
public function foo($parameter = null) {
    $parameter = $parameter ? $parameter : $this->_calculateDefault();
    // ...
}

// New:
public function foo($parameter = null) {
    $parameter = $parameter ?: $this->_calculateDefault();
    // ...
}
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|htaccess|jpg|png|gif|css|js|ico|json|ini)$/'
);

$archive->compress(Phar::GZ);
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
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')
)
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);
Lambdas & Closures
$findActive = function($object) use (&$findActive) {
    if ($object->isActive) {
        return $object;
    }
    if ($object->children) {
        foreach ($object->children as $child) {
            return $findActive($child);
        }
    }
};
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;
    }
}
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();
        // ...
    }
}
Lambdas & Closures
class Database {

    public $callThisOnEveryRead;

    public function read($query) {
        if ($callback = $this->callThisOnEveryRead) {
            $callback($query);
        }
        // ...
    }
}
Lambdas & Closures
class Database {

    public $callThisOnEveryRead;

    public function read($query) {
        if ($callback = $this->callThisOnEveryRead) {
            $result = $callback($query)
            if ($result !== null) {
                return $result;
            }
        }
        // ...
    }
}
No $this
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()
lithiumutilcollectionFilters
Method Filters

class Database {

    public function read($query) {
        // ... run the query ...
        return $result;
    }
}
Method Filters

class Database {

    public function read($query) {
        $method = function() {
            // ... run the query ...
            return $result;
        };
    }
}
Method Filters

class Database {

    public function read($query) {
        $method = function($query) {
            // ... run the query ...
            return $result;
        };
        return $method($query);
    }
}
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
        );
    }
}
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;
});
lithiumutilcollectionFilters



             outer


             inner


            read()
AOP in a Nutshell

• Obliviousness
• Eliminates boilerplate code per class
   relationship

• Centralized configuration of concerns
Thanks!

• nate.abele@gmail.com
• @nateabele
• http://lithify.me/

Contenu connexe

Tendances

Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Tatsuhiko Miyagawa
 
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stackBootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bram Vogelaar
 

Tendances (20)

Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 
New Design of OneRing
New Design of OneRingNew Design of OneRing
New Design of OneRing
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyoエラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
エラー時にログに出力する情報と画面に表示する情報を分ける #LaravelTokyo
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stackBootstrap your Cloud Infrastructure using puppet and hashicorp stack
Bootstrap your Cloud Infrastructure using puppet and hashicorp stack
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
Beyond Phoenix
Beyond PhoenixBeyond Phoenix
Beyond Phoenix
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoa
 
Observability with Consul Connect
Observability with Consul ConnectObservability with Consul Connect
Observability with Consul Connect
 
Plack - LPW 2009
Plack - LPW 2009Plack - LPW 2009
Plack - LPW 2009
 
Testing your infrastructure with litmus
Testing your infrastructure with litmusTesting your infrastructure with litmus
Testing your infrastructure with litmus
 
Finch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with FinagleFinch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with Finagle
 
Intro to PSGI and Plack
Intro to PSGI and PlackIntro to PSGI and Plack
Intro to PSGI and Plack
 
Sane Sharding with Akka Cluster
Sane Sharding with Akka ClusterSane Sharding with Akka Cluster
Sane Sharding with Akka Cluster
 

En vedette

Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12
Hitesh Patel
 
Php tutorial
Php tutorialPhp tutorial
Php tutorial
Niit
 

En vedette (10)

Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12Bca sem 6 php practicals 1to12
Bca sem 6 php practicals 1to12
 
Measuring Your Code
Measuring Your CodeMeasuring Your Code
Measuring Your Code
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Measuring Your Code 2.0
Measuring Your Code 2.0Measuring Your Code 2.0
Measuring Your Code 2.0
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 
Building Apps with MongoDB
Building Apps with MongoDBBuilding Apps with MongoDB
Building Apps with MongoDB
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Practical PHP Deployment with Jenkins
Practical PHP Deployment with JenkinsPractical PHP Deployment with Jenkins
Practical PHP Deployment with Jenkins
 
Php tutorial
Php tutorialPhp tutorial
Php tutorial
 

Similaire à Practical PHP 5.3

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
jsmith92
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
jsmith92
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
elliando dias
 

Similaire à Practical PHP 5.3 (20)

PHP 5.3 Overview
PHP 5.3 OverviewPHP 5.3 Overview
PHP 5.3 Overview
 
SPL: The Missing Link in Development
SPL: The Missing Link in DevelopmentSPL: The Missing Link in Development
SPL: The Missing Link in Development
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Introduction to php oop
Introduction to php oopIntroduction to php oop
Introduction to php oop
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
PHP and Rich Internet Applications
PHP and Rich Internet ApplicationsPHP and Rich Internet Applications
PHP and Rich Internet Applications
 
All I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web FrameworkAll I Need to Know I Learned by Writing My Own Web Framework
All I Need to Know I Learned by Writing My Own Web Framework
 
Modern php
Modern phpModern php
Modern php
 
Php Tutorials for Beginners
Php Tutorials for BeginnersPhp Tutorials for Beginners
Php Tutorials for Beginners
 
php AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdfphp AND MYSQL _ppt.pdf
php AND MYSQL _ppt.pdf
 
Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)Preparing for the next PHP version (5.6)
Preparing for the next PHP version (5.6)
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Node.js for PHP developers
Node.js for PHP developersNode.js for PHP developers
Node.js for PHP developers
 
FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3FFW Gabrovo PMG - PHP OOP Part 3
FFW Gabrovo PMG - PHP OOP Part 3
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Php course-in-navimumbai
Php course-in-navimumbaiPhp course-in-navimumbai
Php course-in-navimumbai
 
Modernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul JonesModernizing Legacy Applications in PHP, por Paul Jones
Modernizing Legacy Applications in PHP, por Paul Jones
 
PHP OOP
PHP OOPPHP OOP
PHP OOP
 

Dernier

Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
UK Journal
 

Dernier (20)

Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoft
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
Behind the Scenes From the Manager's Chair: Decoding the Secrets of Successfu...
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 

Practical PHP 5.3

  • 1. Practical PHP 5.3 Nate Abele 2.6.2010 IPC Berlin
  • 2. Me • Former lead developer, CakePHP • Co-founder & current lead developer, Lithium • Developing on 5.3 for ~2 years • Twitter: @nateabele
  • 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.
  • 6. Little Things • Performance • ext/fileinfo • Syntax • ext/sqlite3 • Phar • ext/intl • SPL classes • mysqlnd
  • 7. Big Things • Late static binding • Namespaces • Lambdas / closures
  • 8. 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; } }
  • 9. 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
  • 10. 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?'
  • 11. 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'
  • 12. 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?'
  • 13. Why? • Properly architect stateless portions of apps • Utility classes • Immutable state
  • 14. “Dynamic” statics • $foo->$bar() vs. Foo::bar() • $foo = 'Foo'; $bar = 'bar'; $foo::$bar(); • __callStatic()
  • 15. “Dynamic” statics class Dispatcher { public function run($url) { $parameters = Router::match($url); // ... } }
  • 16. “Dynamic” statics class Dispatcher { public $router = 'Router'; public function run($url) { $router = $this->router; $parameters = $router::match($url); // ... } }
  • 17. Namespaces • Finally! • What’s up with the ? • Actually “packages”
  • 18. Namespaces namespace foobar; class MyClass { // ... } $class = new foobarMyClass(); // -- or -- use foobarMyClass; $class = new MyClass();
  • 19. Namespace use foobar; $class = new barMyClass(); namespace me; $list = new SplDoublyLinkedList(); namespace me; $list = new SplDoublyLinkedList(); namespace me; $class = 'foobarMyClass'; $object = new $class();
  • 21. PSR-0 • Maps top-level vendor package name to filesystem location • Maps file names 1:1 with class name
  • 22. 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
  • 23. Original (PEAR) Draft • Requires sub-packages • Namespaces must be lower-cased and underscored
  • 24. Original (PEAR) Draft • LithiumCore: ? • lithiumcore: Obviously a namespace • Sub-packages promote reuse outside vendor libraries
  • 25. SplClassLoader • Concrete implementation of PSR-0 • PHP version: http://gist.github.com/221634 • C version: http://github.com/metagoto/splclassloader
  • 27. Ternary Shortcut // Old: public function foo($parameter = null) { $parameter = $parameter ? $parameter : $this->_calculateDefault(); // ... } // New: public function foo($parameter = null) { $parameter = $parameter ?: $this->_calculateDefault(); // ... }
  • 28. Phar • include 'phar:///path/to/file.phar/file.php'; • Redistributable apps • Plugins • Application templates
  • 29. 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);
  • 30. 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
  • 31. 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') )
  • 32. 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);
  • 33. Lambdas & Closures $findActive = function($object) use (&$findActive) { if ($object->isActive) { return $object; } if ($object->children) { foreach ($object->children as $child) { return $findActive($child); } } };
  • 34. 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; } }
  • 35. 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(); // ... } }
  • 36. Lambdas & Closures class Database { public $callThisOnEveryRead; public function read($query) { if ($callback = $this->callThisOnEveryRead) { $callback($query); } // ... } }
  • 37. Lambdas & Closures class Database { public $callThisOnEveryRead; public function read($query) { if ($callback = $this->callThisOnEveryRead) { $result = $callback($query) if ($result !== null) { return $result; } } // ... } }
  • 39. 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()
  • 41. Method Filters class Database { public function read($query) { // ... run the query ... return $result; } }
  • 42. Method Filters class Database { public function read($query) { $method = function() { // ... run the query ... return $result; }; } }
  • 43. Method Filters class Database { public function read($query) { $method = function($query) { // ... run the query ... return $result; }; return $method($query); } }
  • 44. 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 ); } }
  • 45. 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; });
  • 46. lithiumutilcollectionFilters outer inner read()
  • 47. AOP in a Nutshell • Obliviousness • Eliminates boilerplate code per class relationship • Centralized configuration of concerns