SlideShare a Scribd company logo
Decoupled Libraries for PHP	

Sunshine PHP	

07 Feb 2014	

!

joind.in/10510	

!

paul-m-jones.com	

@pmjones
Read These
About Me
•

8 years USAF Intelligence	


•

Programming since 1983,

PHP since 1999	


•

Developer, Senior Developer,

Team Lead, Architect,VP Engineering	


•

Aura project, benchmarking series,
Zend_DB, Zend_View	


•

ZCE Advisory Board, PHP-FIG,
PSR-1, PSR-2, PSR-4 (php-fig.org)
Overview

•

Background: Libraries, Frameworks, Components	


•

Principles of decoupled library packages	


•

Examples: individual Aura library packages	


•

Limits to decoupling, direction of dependencies
Background: Libraries, Frameworks,
Components (oh my)
Frameworks: Bad!
•

PHP 3, PHP 4, and early PHP 5: “framework” a bad word

(“content management system” was ok)	


•

Libraries and collections: phpLib, Horde, PEAR, PhpClasses, FreshMeat	


•

Not unified in operation: different constructor signatures, different
method verbiage, different usage idioms, tough to combine	


•

Started Solar (solarphp.com) in late 2004 as a library collection

(first of the PHP 5 E_STRICT collections)
Frameworks: Good! (Round 1)

•

Ruby on Rails (2004/5): “framework” suddenly acceptable	


•

Agavi, Cake, CodeIgniter, ezComponents, Mojavi, PhpOnTrax, Symfony,
Zend Framework, many others	


•

Tapped into developer needs, including tribal belonging and plugins
Frameworks: Good! (Round 2)

•

PHP 5.3 “full stack”: Lithium, Symfony 2, Zend Framework 2, others	


•

Micro-frameworks: Glue, Limonade, Silex, Slim	

•

Context, router+dispatcher, HTTP request/response, middleware
Frameworks: Good?
•

Delivered as a monolithic whole	


•

Want to use just part of a framework? Difficult.	


•

Download entire framework and try to use one part ...	


•

... except it’s coupled to dependencies within the framework.	


•

Have to set up parts you don’t care about.	


•

Components (kind of): Symfony 2, Zend Framework 2
Definitions of “Decoupled”
•

In formal design, decoupling means to make the features of a formal system as
independent as possible from each other. — Ioannis T. Kassios, http://
link.springer.com/chapter/10.1007/11526841_5	


•

Decoupling refers to careful controls that separate code modules from particular
use cases, which increases code re-usability. — https://en.wikipedia.org/wiki/
Object-oriented_programming#Decoupling	


•

Cf. http://www.coldewey.com/publikationen/Decoupling.1.1.PDF	


•

Framework-level and package-level decoupling, not class-level
Zend Framework 2
install:
zend-inputfilter
!

depends:
zend-stdlib
zend-servicemanager
zend-filter
zend-i18n
zend-validator
!

suggest:
pecl-weakref
zendframework/zend-di
zendframework/zend-crypt
zendframework/zend-db
zendframework/zend-math
Symfony 2
•

Symfony Components implement common features needed to develop websites.
They are the foundation of the Symfony full-stack framework, but they can also
be used standalone even if you don't use the framework as they don't have any
mandatory dependencies. — http://symfony.com/components	


•

Symfony’s claim … is clearly true for 11 of those packages … clearly false for
4 of them … debatable for the remaining 6 … 

— http://paul-m-jones.com/archives/4263
How To Tell
•

Composer.json has “require” for another package? Not decoupled.	


•

Composer.json has “require-dev”? Might or might not be decoupled.
(Allowance for interface packages.)	


•

“Optional behavior”? Still coupled. Could say the same for framework.




/** Symfony/Component/Routing/Loader/AnnotationClassLoader.php */

namespace SymfonyComponentRoutingLoader;

use
use
use
use
use
use

DoctrineCommonAnnotationsReader;

SymfonyComponentConfigResourceFileResource;

SymfonyComponentRoutingRoute;

SymfonyComponentRoutingRouteCollection;

SymfonyComponentConfigLoaderLoaderInterface;

SymfonyComponentConfigLoaderLoaderResolverInterface;
Decoupled Components?

•

Not dependent on framework but still dependent on each other

•

Ed Finkler, “The Micro-PHP Manifesto” (microphp.org)
Principles of Decoupled Packages
Rewrite Solar as Aura
•

Solar Framework: 5+ years old at the time (Oct 2010)	


•

Monolithic; tough to use just parts of it	


•

Independent, decoupled library packages	


•

V1 (Oct 2010): extract components, PSR-0	


•

V2 (Sep 2013): split packages even further, PSR-4
Driving Principles (1)
•

Libraries first, framework later	


•

No use of globals within packages (e.g., pass in $_SERVER)	


•

No dependencies on any other package	


•

Tests and assets encapsulated within package	


•

No “composer install" to run tests or get extra/optional functionality	


•

Each has its own repository (no subtree splits or extract-and-build)
Library Package Organization
Driving Principles (2):

Dependency Injection
•

Solar used static Service Locator and universal constructor	


•

In Aura, a shared Service Locator would mean a package dependency	


•

All packages are set up for dependency injection	


•

You can use any container you like (Aura.Di is nice ;-) or none	


•

Pass Factory objects instead of using new (reveals dependencies)
new Example
class Foo

{

protected $db;

public function __construct()

{

$this->db = new Database(...);

}

}

Service Locator Examples
class Foo

{

protected $db;

public function __construct()

{

$this->db = Locator::get('db');

}

}

class Foo

{

protected $db;

public function __construct(Locator $locator)

{

$this->db = $locator->get('db');

}

}

Dependency Injection Examples
class Foo

{

protected $db;

public function __construct(Database $db)

{

$this->db = $db;

}

}

class Foo

{

protected $db;

public function setDb(Database $db)

{

$this->db = $db;

}

}

How To Tell Dependency Injection

from Service Locator
•

Both build and retain service objects: usage, not implementation	


•

Any DI container instance can be injected into an object	


•

Any SL container instance can be kept outside an object	


•

Providing static methods on Container: Service Locator	


•

implements ContainerAware:

•

Container

Service Locator	


parameter typehint: Service Locator
Dependency Injection > Service Locator
•

Service Locator hides dependencies	


•

Service Locator is itself a dependency (all libraries need it)	


•

Harder to write tests for objects using the Service Locator	


•

DI reveals dependencies (especially with Factories)	


•

Is not itself a dependency	


•

Easier to write tests, fakes, etc.	


•

Service Locator instance, if needed, on a per-package basis
Aura.Router v2
Description
Provides a web router implementation:
given a URL path and a copy of $_SERVER,
it will extract path-info parameters and
$_SERVER values for a specific route.
Instantiation
require '/path/to/Aura.Router/autoload.php';







use AuraRouterRouterFactory;

$router_factory = new RouterFactory;

$router = $router_factory->newInstance();

use AuraRouterRouter;

use AuraRouterRouteCollection;

use AuraRouterRouteFactory;

$router = new Router(new RouteCollection(new RouteFactory));
Adding Routes
// add an unnamed route with params

$router->add(null, '/{controller}/{action}/{id}');




// add a named route with optional params

$router->add('archive', '/archive{/year,month,day}');







// add a named route with an extended specification

$router->add('read', '/blog/read/{id}{format}')

->addTokens(array(

'id'
=> 'd+',

'format' => '(.[^/]+)?',

))

->addValues(array(

'controller' => 'blog',

'action'
=> 'read',

'format'
=> '.html',

));

// add a REST route: BREAD+CUR

$router->attachResource('users', '/users');

Matching Routes
// get the incoming request URI path

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);




// get the route based on the path and server

$route = $router->match($path, $_SERVER);


The match() method does not parse the URI or use
$_SERVER internally. This is because different systems may
have different ways of representing that information; e.g.,
through a URI object or a context object. As long as you
can pass the string path and a server array, you can use
Aura.Router in your application foundation or framework.
Route Parameters



$route = $router->match('/blog/read/42.json', $_SERVER);

var_export($route->params);

// shows these values:

[

'controller' => 'blog',

'action'
=> 'read',

'id'
=> '42',

'format'
=> '.json',

]

Dispatching Routes
$params = $route->params;

$class = ucfirst($params['controller']) . 'Page';

$method = $params['action'] . 'Action';

$object = new $class();

echo $object->$method($params);

Micro-Framework Route
$router->add('read', '/blog/read/{id}')

->addTokens(array(

'id' => 'd+',

))

->addValues(array(

'controller' => function ($params) {

$id = (int) $params['id'];

header('Content-Type: application/json');

echo json_encode(['id' => $id]);

},

));

Micro-Framework Dispatcher

$controller = $route->params['controller'];

echo $controller($route->params);

Aura.Web (v1 to v2)
Old (v1) Description
Provides tools to build web page controllers,
including an `AbstractPage` for action methods, a
`Context` class for discovering the request
environment, and a `Response` transfer object that
describes the eventual HTTP response.
Instantiation and Calling



use
use
use
use
use
use

VendorPackageWebPage;

AuraWebContext;

AuraWebAccept;

AuraWebResponse;

AuraWebSignal;

AuraWebRendererNone as Renderer;


$params = [

'action' => 'hello',

'format' => '.html',

'noun'
=> 'world',

];







$page = new Page(

new Context($GLOBALS),

new Accept($_SERVER),

new Response,

new Signal,

new Renderer,

$params

);

$response = $page->exec();

Important Parts
for incoming parameters	


•

$this->params

•

$this->context

•

$this->accept

•

$this->response

•

$this->signal

•

$this->renderer

•

$this->data

•

(pre|post)_(exec|action|render)

for get, post, files, etc.	


for content-type, language, encoding, etc	

for headers, cookies, content (data transfer object)	


for signals/events/notifiers (separated interface)	

for rendering strategy (default “none”)	


for data to be rendered	

hooks, and catch_exception hook
Rendering Strategy

class NaiveRenderer extends AbstractRenderer

{

public function exec()

{

// get data from controller

$data = (array) $this->controller->getData();




// pick a template file based on controller action

$action
= $this->controller->getAction();

$__file__ = "/path/to/templates/{$action}.php";




// closure to execute template file

$template = function () use (array $data, $__file__) {

ob_start();

extract($data);

require $__file__;

return ob_get_clean();

};




// invoke closure

$content = $template();




// set content on response, and done!

$response = $this->controller->getResponse();

$response->setContent($content);

}

}

Way Too Much In v1
•

At first, all seemed to go together: base controller, page controller, action
method dispatch, event signals, request, response, rendering	


•

Even with separated interfaces, all coupled to each other	


•

Extract Aura.Dispatcher from Aura.Web, Aura.Cli, front-controller	


•

No more need for “controller” or “rendering” code	


•

All that remains is request and response for your own controllers
New (v2) Description
Provides web Request and Response objects for use
by web controllers. These are representations of the
PHP web environment, not HTTP request and
response objects proper.
Request Object

•

Not an HTTP request, but a web execution context representation	


•

If you have $_SESSION or $_ENV in your request object, it’s not HTTP	


•

Read superglobals, headers, cookies, negotiate accept values, etc.	


•

Read/write on “params”
Response Object

•

Not an HTTP response, but a Data Transfer Object	


•

Must convert it to a real HTTP response (does not “send itself”)	


•

Allows any HTTP library, or none



// typical full-stack controller, dependency injection

class MyAppController

{

public function __construct(

Request $request,

Response $response

) {

$this->request = $request;

$this->response = $response;

}



public function foo()

{

$bar = $this->request->post->get('bar');

$this->response->content->setType('application/json');

}

}

// typical micro-framework route+dispatch+logic, service locator

$app->addGet('/foo', function () use ($app) {

$bar = $app->request->post->get('bar');

$app->response->content->setType('application/json');

});

Delivery Code
// send status line

header($response->status->get(), true, $response->status->getCode());




// send non-cookie headers

foreach ($response->headers->get() as $label => $value) {

header("{$label}: {$value}");

}







// send cookies

foreach ($response->cookies->get() as $name => $cookie) {

setcookie(

$name,

$cookie['value'],

$cookie['expire'],

$cookie['path'],

$cookie['domain'],

$cookie['secure'],

$cookie['httponly']

);

}

// send content

echo $response->content->get();

Limits To Decoupling
Library Packages
•Aura.Autoload

•Aura.Marshal	


•Aura.Cli

•Aura.Router

•Aura.Di

•Aura.Session	


•Aura.Dispatcher

•Aura.Signal	


•Aura.Filter	


•Aura.Sql

•Aura.Html

•Aura.Sql_Query

•Aura.Http	


•Aura.Sql_Schema

•Aura.Includer

•Aura.Uri	


•Aura.Input	


•Aura.View

•Aura.Intl	


•Aura.Web
Combinations Mean Dependencies

•

Front controller will need router, dispatcher, responder	


•

Action controller will need services, request/response	


•

Gateway services will need data source connection
Clean Code (Robert C. Martin)
*_Kernel, *_Project

•

“Kernel” of packages and glue	


•

“Project” (framework) skeleton	


•

composer create-project
Watch For Dependency/Coupling

•

Controller should probably be independent of routing, dispatching,
external base class (and vice versa)	


•

Service Locators are especially binding	


•

Micro-frameworks are antithesis of decoupling: closure is bound to
routing, dispatching, locator (and probably middleware system)
Conclusion
•

Background: Libraries, Frameworks, Components	


•

Principles of decoupled library packages	


•

Examples: individual Aura library packages	


•

Limits to decoupling, direction of dependencies
Modernizing Legacy Applications in PHP
Are you overwhelmed by a legacy application full of page scripts,
spaghetti includes, and global variables? Do you want to improve the
quality of the code, but don’t know where to begin or how to proceed?	

!

My new book, Modernizing Legacy Applications in PHP, gives step-bystep instructions on how to get your code under control and keep
your application running the whole time.	

!

http://mlaphp.com
!

Buy the early access version now and get free updates as it is
completed, or sign up on the mailing list below for more information
and a free sample chapter.
Thanks!
!

auraphp.com	

!

paul-m-jones.com	

@pmjones	

!

mlaphp.com	

!

joind.in/10510

More Related Content

What's hot

Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
Elizabeth Smith
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
Elizabeth Smith
 
Solr Black Belt Pre-conference
Solr Black Belt Pre-conferenceSolr Black Belt Pre-conference
Solr Black Belt Pre-conferenceErik Hatcher
 
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf
DSpace UI Prototype Challenge: Spring Boot + ThymeleafDSpace UI Prototype Challenge: Spring Boot + Thymeleaf
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf
Tim Donohue
 
Spl to the Rescue - Zendcon 09
Spl to the Rescue - Zendcon 09Spl to the Rescue - Zendcon 09
Spl to the Rescue - Zendcon 09
Elizabeth Smith
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with SolrErik Hatcher
 
Lucene for Solr Developers
Lucene for Solr DevelopersLucene for Solr Developers
Lucene for Solr DevelopersErik Hatcher
 
Network programming
Network programmingNetwork programming
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
Elizabeth Smith
 
Z ray plugins for dummies
Z ray plugins for dummiesZ ray plugins for dummies
Z ray plugins for dummies
Dmitry Zbarski
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)
Win Yu
 
code4lib 2011 preconference: What's New in Solr (since 1.4.1)
code4lib 2011 preconference: What's New in Solr (since 1.4.1)code4lib 2011 preconference: What's New in Solr (since 1.4.1)
code4lib 2011 preconference: What's New in Solr (since 1.4.1)
Erik Hatcher
 
eZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedeZ Publish Cluster Unleashed
eZ Publish Cluster Unleashed
Bertrand Dunogier
 
Content Modeling Behavior
Content Modeling BehaviorContent Modeling Behavior
Content Modeling Behavior
Alfresco Software
 
SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09
Elizabeth Smith
 
Solr 4
Solr 4Solr 4
Solr 4
Erik Hatcher
 
Introduction To Ant
Introduction To AntIntroduction To Ant
Introduction To Ant
Rajesh Kumar
 
Solr Powered Lucene
Solr Powered LuceneSolr Powered Lucene
Solr Powered Lucene
Erik Hatcher
 

What's hot (20)

Php on the desktop and php gtk2
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
Solr Black Belt Pre-conference
Solr Black Belt Pre-conferenceSolr Black Belt Pre-conference
Solr Black Belt Pre-conference
 
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf
DSpace UI Prototype Challenge: Spring Boot + ThymeleafDSpace UI Prototype Challenge: Spring Boot + Thymeleaf
DSpace UI Prototype Challenge: Spring Boot + Thymeleaf
 
Spl to the Rescue - Zendcon 09
Spl to the Rescue - Zendcon 09Spl to the Rescue - Zendcon 09
Spl to the Rescue - Zendcon 09
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 
Lucene for Solr Developers
Lucene for Solr DevelopersLucene for Solr Developers
Lucene for Solr Developers
 
Network programming
Network programmingNetwork programming
Network programming
 
Streams, sockets and filters oh my!
Streams, sockets and filters oh my!Streams, sockets and filters oh my!
Streams, sockets and filters oh my!
 
rtwerewr
rtwerewrrtwerewr
rtwerewr
 
Z ray plugins for dummies
Z ray plugins for dummiesZ ray plugins for dummies
Z ray plugins for dummies
 
Spl in the wild
Spl in the wildSpl in the wild
Spl in the wild
 
PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)PHP 良好實踐 (Best Practice)
PHP 良好實踐 (Best Practice)
 
code4lib 2011 preconference: What's New in Solr (since 1.4.1)
code4lib 2011 preconference: What's New in Solr (since 1.4.1)code4lib 2011 preconference: What's New in Solr (since 1.4.1)
code4lib 2011 preconference: What's New in Solr (since 1.4.1)
 
eZ Publish Cluster Unleashed
eZ Publish Cluster UnleashedeZ Publish Cluster Unleashed
eZ Publish Cluster Unleashed
 
Content Modeling Behavior
Content Modeling BehaviorContent Modeling Behavior
Content Modeling Behavior
 
SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09SPL to the Rescue - Tek 09
SPL to the Rescue - Tek 09
 
Solr 4
Solr 4Solr 4
Solr 4
 
Introduction To Ant
Introduction To AntIntroduction To Ant
Introduction To Ant
 
Solr Powered Lucene
Solr Powered LuceneSolr Powered Lucene
Solr Powered Lucene
 

Viewers also liked

The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)
Paul Jones
 
All You Jokers
All You JokersAll You Jokers
All You JokersPaul Jones
 
Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)
Paul Jones
 
Same Thing Happens Every Time
Same Thing Happens Every TimeSame Thing Happens Every Time
Same Thing Happens Every Time
Paul Jones
 
How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?Paul Jones
 
Framework and Application Benchmarking
Framework and Application BenchmarkingFramework and Application Benchmarking
Framework and Application BenchmarkingPaul Jones
 
Action-Domain-Responder: A Refinement of MVC
Action-Domain-Responder: A Refinement of MVCAction-Domain-Responder: A Refinement of MVC
Action-Domain-Responder: A Refinement of MVC
Paul Jones
 
PHP-VCR Lightningtalk
PHP-VCR LightningtalkPHP-VCR Lightningtalk
PHP-VCR Lightningtalk
Adrian Philipp
 
How To Train Your Manager
How To Train Your ManagerHow To Train Your Manager
How To Train Your Manager
Paul Jones
 
PHP-VCR behat case study
PHP-VCR behat case studyPHP-VCR behat case study
PHP-VCR behat case study
Pascal Thormeier
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Paul Jones
 
Career and Life Management
Career and Life ManagementCareer and Life Management
Career and Life ManagementPaul Jones
 
Unit Test + Functional Programming = Love
Unit Test + Functional Programming = LoveUnit Test + Functional Programming = Love
Unit Test + Functional Programming = Love
Alvaro Videla
 

Viewers also liked (13)

The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)The Solar Framework for PHP 5 (2010 Confoo)
The Solar Framework for PHP 5 (2010 Confoo)
 
All You Jokers
All You JokersAll You Jokers
All You Jokers
 
Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)Organinzing Your PHP Projects (2010 Memphis PHP)
Organinzing Your PHP Projects (2010 Memphis PHP)
 
Same Thing Happens Every Time
Same Thing Happens Every TimeSame Thing Happens Every Time
Same Thing Happens Every Time
 
How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?How Do We Get The Deficit To Zero?
How Do We Get The Deficit To Zero?
 
Framework and Application Benchmarking
Framework and Application BenchmarkingFramework and Application Benchmarking
Framework and Application Benchmarking
 
Action-Domain-Responder: A Refinement of MVC
Action-Domain-Responder: A Refinement of MVCAction-Domain-Responder: A Refinement of MVC
Action-Domain-Responder: A Refinement of MVC
 
PHP-VCR Lightningtalk
PHP-VCR LightningtalkPHP-VCR Lightningtalk
PHP-VCR Lightningtalk
 
How To Train Your Manager
How To Train Your ManagerHow To Train Your Manager
How To Train Your Manager
 
PHP-VCR behat case study
PHP-VCR behat case studyPHP-VCR behat case study
PHP-VCR behat case study
 
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-ControllerAction-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
Action-Domain-Responder: A Web-Specific Refinement of Model-View-Controller
 
Career and Life Management
Career and Life ManagementCareer and Life Management
Career and Life Management
 
Unit Test + Functional Programming = Love
Unit Test + Functional Programming = LoveUnit Test + Functional Programming = Love
Unit Test + Functional Programming = Love
 

Similar to Decoupled Libraries for PHP

D7 entities fields
D7 entities fieldsD7 entities fields
D7 entities fields
cyberswat
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
Gordon Forsythe
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
Oscar Merida
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet CampPuppet
 
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Antonio Peric-Mazar
 
L04 base patterns
L04 base patternsL04 base patterns
L04 base patterns
Ólafur Andri Ragnarsson
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...King Foo
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend framework
Saidur Rahman
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
Darren Craig
 
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
Wong Hoi Sing Edison
 
Puppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutesPuppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutes
Alessandro Franceschi
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoveragemlilley
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
Alan Seiden
 
Edp bootstrapping a-software_company
Edp bootstrapping a-software_companyEdp bootstrapping a-software_company
Edp bootstrapping a-software_companyGanesh Kulkarni
 
Puppet camp london nov 2014 slides (1)
Puppet camp london nov 2014   slides (1)Puppet camp london nov 2014   slides (1)
Puppet camp london nov 2014 slides (1)Puppet
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb
 
Multi Tenancy With Python and Django
Multi Tenancy With Python and DjangoMulti Tenancy With Python and Django
Multi Tenancy With Python and Django
scottcrespo
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to TornadoGavin Roy
 
Introduction to firebidSQL 3.x
Introduction to firebidSQL 3.xIntroduction to firebidSQL 3.x
Introduction to firebidSQL 3.x
Fabio Codebue
 

Similar to Decoupled Libraries for PHP (20)

D7 entities fields
D7 entities fieldsD7 entities fields
D7 entities fields
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Staying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHPStaying Sane with Drupal NEPHP
Staying Sane with Drupal NEPHP
 
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Campmodern module development - Ken Barber 2012 Edinburgh Puppet Camp
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
 
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
 
L04 base patterns
L04 base patternsL04 base patterns
L04 base patterns
 
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
Building Web Services with Zend Framework (PHP Benelux meeting 20100713 Vliss...
 
Getting up & running with zend framework
Getting up & running with zend frameworkGetting up & running with zend framework
Getting up & running with zend framework
 
Getting up and running with Zend Framework
Getting up and running with Zend FrameworkGetting up and running with Zend Framework
Getting up and running with Zend Framework
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
[HKDUG] #20161210 - BarCamp Hong Kong 2016 - What's News in PHP?
 
Puppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutesPuppet: From 0 to 100 in 30 minutes
Puppet: From 0 to 100 in 30 minutes
 
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverageTesting NodeJS with Mocha, Should, Sinon, and JSCoverage
Testing NodeJS with Mocha, Should, Sinon, and JSCoverage
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
 
Edp bootstrapping a-software_company
Edp bootstrapping a-software_companyEdp bootstrapping a-software_company
Edp bootstrapping a-software_company
 
Puppet camp london nov 2014 slides (1)
Puppet camp london nov 2014   slides (1)Puppet camp london nov 2014   slides (1)
Puppet camp london nov 2014 slides (1)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Multi Tenancy With Python and Django
Multi Tenancy With Python and DjangoMulti Tenancy With Python and Django
Multi Tenancy With Python and Django
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
Introduction to firebidSQL 3.x
Introduction to firebidSQL 3.xIntroduction to firebidSQL 3.x
Introduction to firebidSQL 3.x
 

Recently uploaded

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
Elena Simperl
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
Peter Spielvogel
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 

Recently uploaded (20)

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...When stars align: studies in data quality, knowledge graphs, and machine lear...
When stars align: studies in data quality, knowledge graphs, and machine lear...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfSAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 

Decoupled Libraries for PHP

  • 1. Decoupled Libraries for PHP Sunshine PHP 07 Feb 2014 ! joind.in/10510 ! paul-m-jones.com @pmjones
  • 3. About Me • 8 years USAF Intelligence • Programming since 1983,
 PHP since 1999 • Developer, Senior Developer,
 Team Lead, Architect,VP Engineering • Aura project, benchmarking series, Zend_DB, Zend_View • ZCE Advisory Board, PHP-FIG, PSR-1, PSR-2, PSR-4 (php-fig.org)
  • 4. Overview • Background: Libraries, Frameworks, Components • Principles of decoupled library packages • Examples: individual Aura library packages • Limits to decoupling, direction of dependencies
  • 6. Frameworks: Bad! • PHP 3, PHP 4, and early PHP 5: “framework” a bad word
 (“content management system” was ok) • Libraries and collections: phpLib, Horde, PEAR, PhpClasses, FreshMeat • Not unified in operation: different constructor signatures, different method verbiage, different usage idioms, tough to combine • Started Solar (solarphp.com) in late 2004 as a library collection
 (first of the PHP 5 E_STRICT collections)
  • 7. Frameworks: Good! (Round 1) • Ruby on Rails (2004/5): “framework” suddenly acceptable • Agavi, Cake, CodeIgniter, ezComponents, Mojavi, PhpOnTrax, Symfony, Zend Framework, many others • Tapped into developer needs, including tribal belonging and plugins
  • 8. Frameworks: Good! (Round 2) • PHP 5.3 “full stack”: Lithium, Symfony 2, Zend Framework 2, others • Micro-frameworks: Glue, Limonade, Silex, Slim • Context, router+dispatcher, HTTP request/response, middleware
  • 9. Frameworks: Good? • Delivered as a monolithic whole • Want to use just part of a framework? Difficult. • Download entire framework and try to use one part ... • ... except it’s coupled to dependencies within the framework. • Have to set up parts you don’t care about. • Components (kind of): Symfony 2, Zend Framework 2
  • 10. Definitions of “Decoupled” • In formal design, decoupling means to make the features of a formal system as independent as possible from each other. — Ioannis T. Kassios, http:// link.springer.com/chapter/10.1007/11526841_5 • Decoupling refers to careful controls that separate code modules from particular use cases, which increases code re-usability. — https://en.wikipedia.org/wiki/ Object-oriented_programming#Decoupling • Cf. http://www.coldewey.com/publikationen/Decoupling.1.1.PDF • Framework-level and package-level decoupling, not class-level
  • 12. Symfony 2 • Symfony Components implement common features needed to develop websites. They are the foundation of the Symfony full-stack framework, but they can also be used standalone even if you don't use the framework as they don't have any mandatory dependencies. — http://symfony.com/components • Symfony’s claim … is clearly true for 11 of those packages … clearly false for 4 of them … debatable for the remaining 6 … 
 — http://paul-m-jones.com/archives/4263
  • 13. How To Tell • Composer.json has “require” for another package? Not decoupled. • Composer.json has “require-dev”? Might or might not be decoupled. (Allowance for interface packages.) • “Optional behavior”? Still coupled. Could say the same for framework. 
 /** Symfony/Component/Routing/Loader/AnnotationClassLoader.php */
 namespace SymfonyComponentRoutingLoader;
 use use use use use use DoctrineCommonAnnotationsReader;
 SymfonyComponentConfigResourceFileResource;
 SymfonyComponentRoutingRoute;
 SymfonyComponentRoutingRouteCollection;
 SymfonyComponentConfigLoaderLoaderInterface;
 SymfonyComponentConfigLoaderLoaderResolverInterface;
  • 14. Decoupled Components? • Not dependent on framework but still dependent on each other • Ed Finkler, “The Micro-PHP Manifesto” (microphp.org)
  • 16. Rewrite Solar as Aura • Solar Framework: 5+ years old at the time (Oct 2010) • Monolithic; tough to use just parts of it • Independent, decoupled library packages • V1 (Oct 2010): extract components, PSR-0 • V2 (Sep 2013): split packages even further, PSR-4
  • 17. Driving Principles (1) • Libraries first, framework later • No use of globals within packages (e.g., pass in $_SERVER) • No dependencies on any other package • Tests and assets encapsulated within package • No “composer install" to run tests or get extra/optional functionality • Each has its own repository (no subtree splits or extract-and-build)
  • 19. Driving Principles (2):
 Dependency Injection • Solar used static Service Locator and universal constructor • In Aura, a shared Service Locator would mean a package dependency • All packages are set up for dependency injection • You can use any container you like (Aura.Di is nice ;-) or none • Pass Factory objects instead of using new (reveals dependencies)
  • 20. new Example class Foo
 {
 protected $db;
 public function __construct()
 {
 $this->db = new Database(...);
 }
 }

  • 21. Service Locator Examples class Foo
 {
 protected $db;
 public function __construct()
 {
 $this->db = Locator::get('db');
 }
 }

  • 22. class Foo
 {
 protected $db;
 public function __construct(Locator $locator)
 {
 $this->db = $locator->get('db');
 }
 }

  • 23. Dependency Injection Examples class Foo
 {
 protected $db;
 public function __construct(Database $db)
 {
 $this->db = $db;
 }
 }

  • 24. class Foo
 {
 protected $db;
 public function setDb(Database $db)
 {
 $this->db = $db;
 }
 }

  • 25. How To Tell Dependency Injection
 from Service Locator • Both build and retain service objects: usage, not implementation • Any DI container instance can be injected into an object • Any SL container instance can be kept outside an object • Providing static methods on Container: Service Locator • implements ContainerAware: • Container Service Locator parameter typehint: Service Locator
  • 26. Dependency Injection > Service Locator • Service Locator hides dependencies • Service Locator is itself a dependency (all libraries need it) • Harder to write tests for objects using the Service Locator • DI reveals dependencies (especially with Factories) • Is not itself a dependency • Easier to write tests, fakes, etc. • Service Locator instance, if needed, on a per-package basis
  • 28. Description Provides a web router implementation: given a URL path and a copy of $_SERVER, it will extract path-info parameters and $_SERVER values for a specific route.
  • 29. Instantiation require '/path/to/Aura.Router/autoload.php';
 
 
 use AuraRouterRouterFactory;
 $router_factory = new RouterFactory;
 $router = $router_factory->newInstance();
 use AuraRouterRouter;
 use AuraRouterRouteCollection;
 use AuraRouterRouteFactory;
 $router = new Router(new RouteCollection(new RouteFactory));
  • 30. Adding Routes // add an unnamed route with params
 $router->add(null, '/{controller}/{action}/{id}');
 
 // add a named route with optional params
 $router->add('archive', '/archive{/year,month,day}');
 
 
 // add a named route with an extended specification
 $router->add('read', '/blog/read/{id}{format}')
 ->addTokens(array(
 'id' => 'd+',
 'format' => '(.[^/]+)?',
 ))
 ->addValues(array(
 'controller' => 'blog',
 'action' => 'read',
 'format' => '.html',
 ));
 // add a REST route: BREAD+CUR
 $router->attachResource('users', '/users');

  • 31. Matching Routes // get the incoming request URI path
 $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
 
 // get the route based on the path and server
 $route = $router->match($path, $_SERVER);
 The match() method does not parse the URI or use $_SERVER internally. This is because different systems may have different ways of representing that information; e.g., through a URI object or a context object. As long as you can pass the string path and a server array, you can use Aura.Router in your application foundation or framework.
  • 32. Route Parameters 
 $route = $router->match('/blog/read/42.json', $_SERVER);
 var_export($route->params);
 // shows these values:
 [
 'controller' => 'blog',
 'action' => 'read',
 'id' => '42',
 'format' => '.json',
 ]

  • 33. Dispatching Routes $params = $route->params;
 $class = ucfirst($params['controller']) . 'Page';
 $method = $params['action'] . 'Action';
 $object = new $class();
 echo $object->$method($params);

  • 34. Micro-Framework Route $router->add('read', '/blog/read/{id}')
 ->addTokens(array(
 'id' => 'd+',
 ))
 ->addValues(array(
 'controller' => function ($params) {
 $id = (int) $params['id'];
 header('Content-Type: application/json');
 echo json_encode(['id' => $id]);
 },
 ));

  • 35. Micro-Framework Dispatcher $controller = $route->params['controller'];
 echo $controller($route->params);

  • 37. Old (v1) Description Provides tools to build web page controllers, including an `AbstractPage` for action methods, a `Context` class for discovering the request environment, and a `Response` transfer object that describes the eventual HTTP response.
  • 38. Instantiation and Calling 
 use use use use use use VendorPackageWebPage;
 AuraWebContext;
 AuraWebAccept;
 AuraWebResponse;
 AuraWebSignal;
 AuraWebRendererNone as Renderer;
 $params = [
 'action' => 'hello',
 'format' => '.html',
 'noun' => 'world',
 ];
 
 
 $page = new Page(
 new Context($GLOBALS),
 new Accept($_SERVER),
 new Response,
 new Signal,
 new Renderer,
 $params
 );
 $response = $page->exec();

  • 39. Important Parts for incoming parameters • $this->params • $this->context • $this->accept • $this->response • $this->signal • $this->renderer • $this->data • (pre|post)_(exec|action|render) for get, post, files, etc. for content-type, language, encoding, etc for headers, cookies, content (data transfer object) for signals/events/notifiers (separated interface) for rendering strategy (default “none”) for data to be rendered hooks, and catch_exception hook
  • 40. Rendering Strategy class NaiveRenderer extends AbstractRenderer
 {
 public function exec()
 {
 // get data from controller
 $data = (array) $this->controller->getData();
 
 // pick a template file based on controller action
 $action = $this->controller->getAction();
 $__file__ = "/path/to/templates/{$action}.php";
 
 // closure to execute template file
 $template = function () use (array $data, $__file__) {
 ob_start();
 extract($data);
 require $__file__;
 return ob_get_clean();
 };
 
 // invoke closure
 $content = $template();
 
 // set content on response, and done!
 $response = $this->controller->getResponse();
 $response->setContent($content);
 }
 }

  • 41. Way Too Much In v1 • At first, all seemed to go together: base controller, page controller, action method dispatch, event signals, request, response, rendering • Even with separated interfaces, all coupled to each other • Extract Aura.Dispatcher from Aura.Web, Aura.Cli, front-controller • No more need for “controller” or “rendering” code • All that remains is request and response for your own controllers
  • 42. New (v2) Description Provides web Request and Response objects for use by web controllers. These are representations of the PHP web environment, not HTTP request and response objects proper.
  • 43. Request Object • Not an HTTP request, but a web execution context representation • If you have $_SESSION or $_ENV in your request object, it’s not HTTP • Read superglobals, headers, cookies, negotiate accept values, etc. • Read/write on “params”
  • 44. Response Object • Not an HTTP response, but a Data Transfer Object • Must convert it to a real HTTP response (does not “send itself”) • Allows any HTTP library, or none
  • 45. 
 // typical full-stack controller, dependency injection
 class MyAppController
 {
 public function __construct(
 Request $request,
 Response $response
 ) {
 $this->request = $request;
 $this->response = $response;
 }
 
 public function foo()
 {
 $bar = $this->request->post->get('bar');
 $this->response->content->setType('application/json');
 }
 }
 // typical micro-framework route+dispatch+logic, service locator
 $app->addGet('/foo', function () use ($app) {
 $bar = $app->request->post->get('bar');
 $app->response->content->setType('application/json');
 });

  • 46. Delivery Code // send status line
 header($response->status->get(), true, $response->status->getCode());
 
 // send non-cookie headers
 foreach ($response->headers->get() as $label => $value) {
 header("{$label}: {$value}");
 }
 
 
 // send cookies
 foreach ($response->cookies->get() as $name => $cookie) {
 setcookie(
 $name,
 $cookie['value'],
 $cookie['expire'],
 $cookie['path'],
 $cookie['domain'],
 $cookie['secure'],
 $cookie['httponly']
 );
 }
 // send content
 echo $response->content->get();

  • 49. Combinations Mean Dependencies • Front controller will need router, dispatcher, responder • Action controller will need services, request/response • Gateway services will need data source connection
  • 50. Clean Code (Robert C. Martin)
  • 51. *_Kernel, *_Project • “Kernel” of packages and glue • “Project” (framework) skeleton • composer create-project
  • 52. Watch For Dependency/Coupling • Controller should probably be independent of routing, dispatching, external base class (and vice versa) • Service Locators are especially binding • Micro-frameworks are antithesis of decoupling: closure is bound to routing, dispatching, locator (and probably middleware system)
  • 54. • Background: Libraries, Frameworks, Components • Principles of decoupled library packages • Examples: individual Aura library packages • Limits to decoupling, direction of dependencies
  • 55. Modernizing Legacy Applications in PHP Are you overwhelmed by a legacy application full of page scripts, spaghetti includes, and global variables? Do you want to improve the quality of the code, but don’t know where to begin or how to proceed? ! My new book, Modernizing Legacy Applications in PHP, gives step-bystep instructions on how to get your code under control and keep your application running the whole time. ! http://mlaphp.com ! Buy the early access version now and get free updates as it is completed, or sign up on the mailing list below for more information and a free sample chapter.