ZF2 Modular Architecture - Taking advantage of it

142
ZF2 Modular Architecture Taking Advantage of It PHPDay – Verona, Italy – 18/05/2013

description

Zend Framework 1 had modules. Their name is pretty much everything Zend Framework 2 modules share with them, though. The whole framework architecture has been rewritten to encourage software reuse and extension. In this talk I’ll share our experiences on ZF2 module creation and usage.

Transcript of ZF2 Modular Architecture - Taking advantage of it

Page 1: ZF2 Modular Architecture - Taking advantage of it

ZF2 Modular Architecture Taking Advantage of It

PHPDay – Verona, Italy – 18/05/2013

Page 2: ZF2 Modular Architecture - Taking advantage of it

2

STEVE MARASPIN

Page 3: ZF2 Modular Architecture - Taking advantage of it

3

http://friuli.grusp.org/

Page 4: ZF2 Modular Architecture - Taking advantage of it

MODULES, WHAT?

Picture credits: http://www.flickr.com/photos/10459273@N05/4771563267

Page 5: ZF2 Modular Architecture - Taking advantage of it

A Module is…

5

A collection of code and other files that solves a more specific atomic problem of the larger business problem.

ZF2 RFC

Page 6: ZF2 Modular Architecture - Taking advantage of it

A re-usable piece of functionality that can be used to construct a more complex application.

6

Evan Coury - http://evan.pro/zf2-modules-talk.html

A Module is…

Page 7: ZF2 Modular Architecture - Taking advantage of it

A re-usable piece of functionality that can be used to construct a more complex application.

7

Evan Coury - http://evan.pro/zf2-modules-talk.html

A Module is…

Page 8: ZF2 Modular Architecture - Taking advantage of it

8

Page 9: ZF2 Modular Architecture - Taking advantage of it

• 15.Reuse-in-the-small is a solved problem.

• 16.Reuse-in-the-large remains a mostly unsolved problem.

9

Robert R. Glass – Facts and Fallacies of Software Engineering

About Software Reuse

Page 10: ZF2 Modular Architecture - Taking advantage of it

What I remember about ZF1 Modules…

10

Model

Admin Panel content management, store management, contact requests, ...

Web Site contents, product catalogue, contact form, …

Page 11: ZF2 Modular Architecture - Taking advantage of it

What could we reuse?

11

Model

Admin Panel content management, store management, contact requests, ...

Web Site contents, product catalogue, contact form, …

Page 12: ZF2 Modular Architecture - Taking advantage of it

Picture credits: http://www.flickr.com/photos/cclark395/7671665642/

MEET THE NICE FOLKS

AT OUR COMPANY

Page 13: ZF2 Modular Architecture - Taking advantage of it

INFORMATION DESK

Page 14: ZF2 Modular Architecture - Taking advantage of it

TECHNICAL OFFICE

Picture credits: http://www.flickr.com/photos/ter-burg/5807937726/

Page 15: ZF2 Modular Architecture - Taking advantage of it

WAREHOUSE

Picture credits: http://www.flickr.com/photos/forklifttrainingadelaide/6774324457/

Page 16: ZF2 Modular Architecture - Taking advantage of it

ACCOUNT MANAGER

Page 17: ZF2 Modular Architecture - Taking advantage of it

17

Our Company Hierarchy

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

INFORMATION DESK

DEPARTMENT ONE

DEPARTMENT TWO

Page 18: ZF2 Modular Architecture - Taking advantage of it

18

Customer arrives…

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 19: ZF2 Modular Architecture - Taking advantage of it

19

Information desk greets her

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 20: ZF2 Modular Architecture - Taking advantage of it

20

…gives her directions…

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR. TECHNICAL OFFICE

ACCOUNT MGR.

Page 21: ZF2 Modular Architecture - Taking advantage of it

21

Warehouse folks do things

TECHNICAL OFFICE

ACCOUNT MGR. TECHNICAL OFFICE

WAREHOUSE

ACCOUNT MGR.

Page 22: ZF2 Modular Architecture - Taking advantage of it

22

Stuff is ready for delivery

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 23: ZF2 Modular Architecture - Taking advantage of it

23

Customer is happy.

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 24: ZF2 Modular Architecture - Taking advantage of it

24

Customer is happy. Eventually.

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 25: ZF2 Modular Architecture - Taking advantage of it

25

But Hey…

Page 26: ZF2 Modular Architecture - Taking advantage of it

This is MVC!

26

But Hey…

Page 27: ZF2 Modular Architecture - Taking advantage of it

27

http://framework.zend.com/

Page 28: ZF2 Modular Architecture - Taking advantage of it

28

Our Application

CONTROLLER

VIEW

MODEL

CONTROLLER

VIEW

Page 29: ZF2 Modular Architecture - Taking advantage of it

29

Back to our company…

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

INFORMATION DESK

Page 30: ZF2 Modular Architecture - Taking advantage of it

30

We need to move a dept…

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 31: ZF2 Modular Architecture - Taking advantage of it

31

Dependency problem!

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

Page 32: ZF2 Modular Architecture - Taking advantage of it

32

In our application…

CONTROLLER

VIEW

MODEL

CONTROLLER

VIEW

Page 33: ZF2 Modular Architecture - Taking advantage of it

33

Same Problem!

CONTROLLER

VIEW

MODEL

CONTROLLER

VIEW

Page 34: ZF2 Modular Architecture - Taking advantage of it

34

Solving company problem…

TECHNICAL OFFICE

ACCOUNT MGR.

WAREHOUSE

TECHNICAL OFFICE

ACCOUNT MGR.

INFORMATION DESK

WAREHOUSE

Page 35: ZF2 Modular Architecture - Taking advantage of it

35

Same with our application…

CONTROLLER

VIEW

MODEL

CONTROLLER

VIEW

MODEL

Page 36: ZF2 Modular Architecture - Taking advantage of it

36

Project delivered!

Page 37: ZF2 Modular Architecture - Taking advantage of it

37

Let’s start a new one…

Page 38: ZF2 Modular Architecture - Taking advantage of it

38

Hey, we need this thing!

Page 39: ZF2 Modular Architecture - Taking advantage of it

39

No problems, folks!

MODEL

CONTROLLER

VIEW

Page 40: ZF2 Modular Architecture - Taking advantage of it

40

http://framework.zend.com/

Page 41: ZF2 Modular Architecture - Taking advantage of it

WELCOME ZF2 MODULES

Picture Credits: http://www.flickr.com/photos/10459273@N05/4771563267

Page 42: ZF2 Modular Architecture - Taking advantage of it

42

Namespace Module.php Module

Page 43: ZF2 Modular Architecture - Taking advantage of it

43

Namespace MioModulo;

Class Module {}

Namespace Module.php Module

Simplest Module:

Page 44: ZF2 Modular Architecture - Taking advantage of it

WHAT COULD WE DO WITH IT?

Picture credits: http://www.flickr.com/photos/vittoriomilanes/8286559013

Page 45: ZF2 Modular Architecture - Taking advantage of it

45

Format a date Handle a contact form

Page 46: ZF2 Modular Architecture - Taking advantage of it

46

Format a date Handle a contact form

Handle ACLs Integrate an ORM

Page 47: ZF2 Modular Architecture - Taking advantage of it

47

Format a date Handle a contact form

Handle ACLs Integrate an ORM

Encapsulate a whole application

Page 48: ZF2 Modular Architecture - Taking advantage of it

WHAAAT?

Picture credits: http://www.flickr.com/photos/elzey/3481161467/

Page 49: ZF2 Modular Architecture - Taking advantage of it

49

Format a date Handle a contact form

Handle ACLs Integrate an ORM

Encapsulate a whole application

Page 50: ZF2 Modular Architecture - Taking advantage of it

Let’s think about ZF1 once again…

50

Model

Admin Panel content management, store management, contact requests, ...

Web Site contents, product catalogue, contact form, …

Page 51: ZF2 Modular Architecture - Taking advantage of it

This is how modules are now…

51

Web Site

Model

Admin Panel

Content Management

Page 52: ZF2 Modular Architecture - Taking advantage of it

Focus on features

52

Web Site

Model

Admin Panel

Product Catalogue

Contact Form

Content Management

Page 53: ZF2 Modular Architecture - Taking advantage of it

Focus on features

53

Website

Model

Admin Panel

Product Catalogue

Contact Form

Content Management

Page 54: ZF2 Modular Architecture - Taking advantage of it

What’s in a Module?

54

Feature

Page 55: ZF2 Modular Architecture - Taking advantage of it

What’s in a module?

55

Feature

Controller

Views

PHP Classes

Routing

Configuration

Page 56: ZF2 Modular Architecture - Taking advantage of it

Business Logic Hints

56

Feature

Controller

Viste

PHP Classes

Routing

Configurazioni

Services

Helpers / Plugins

Mappers

Page 57: ZF2 Modular Architecture - Taking advantage of it

LET’S GET OUR HANDS ON IT…

Picture credits: http://www.flickr.com/photos/vittoriomilanes/8286559013

Page 58: ZF2 Modular Architecture - Taking advantage of it

THE SKELETON APP

Picture credits: http://www.flickr.com/photos/fil/144232588/

Page 59: ZF2 Modular Architecture - Taking advantage of it

59

Cloning

git clone

https://github.com/zendframework/ZendSkeletonApplication

Page 60: ZF2 Modular Architecture - Taking advantage of it

60

http://getcomposer.org/

Page 61: ZF2 Modular Architecture - Taking advantage of it

61

composer.json

{

"name": "zendframework/skeleton-application",

"description": "Skeleton Application for ZF2",

"license": "BSD-3-Clause",

"keywords": [

"framework",

"zf2"

],

"homepage": "http://framework.zend.com/",

"require": {

"php": ">=5.3.3",

"zendframework/zendframework": "2.*"

}

}

Page 62: ZF2 Modular Architecture - Taking advantage of it

62

composer.json

{

"name": "zendframework/skeleton-application",

"description": "Skeleton Application for ZF2",

"license": "BSD-3-Clause",

"keywords": [

"framework",

"zf2"

],

"homepage": "http://framework.zend.com/",

"require": {

"php": ">=5.3.3",

"zendframework/zendframework": "2.*"

}

}

Page 63: ZF2 Modular Architecture - Taking advantage of it

63

Installation

cd ZendSkeletonApplication

php composer.phar self-update

php composer.phar install

Page 64: ZF2 Modular Architecture - Taking advantage of it

64

Installation

cd ZendSkeletonApplication

php composer.phar self-update

php composer.phar install

> Installing zendframework/zendframework

Page 65: ZF2 Modular Architecture - Taking advantage of it
Page 66: ZF2 Modular Architecture - Taking advantage of it

66

Filesystem Layout

Page 67: ZF2 Modular Architecture - Taking advantage of it

67

Filesystem Layout

Application Wide Configuration

Page 68: ZF2 Modular Architecture - Taking advantage of it

68

Filesystem Layout

Misc (cached files, documents …)

Page 69: ZF2 Modular Architecture - Taking advantage of it

69

Filesystem Layout

Public DocRoot

Page 70: ZF2 Modular Architecture - Taking advantage of it

70

Filesystem Layout

Our Modules

Page 71: ZF2 Modular Architecture - Taking advantage of it

Filesystem Layout

71

Third Party Modules

Page 72: ZF2 Modular Architecture - Taking advantage of it

Focusing on a module…

72

Module specific configuration

Page 73: ZF2 Modular Architecture - Taking advantage of it

What’s inside a module?

73

Module PHP Source Files (Controller, Form, Model, Services, …)

Page 74: ZF2 Modular Architecture - Taking advantage of it

What’s inside a module?

74

Module test files

Page 75: ZF2 Modular Architecture - Taking advantage of it

What’s inside a module?

75

View stuff (view files, layouts, partials)

Page 76: ZF2 Modular Architecture - Taking advantage of it

LET’S BOOTSTRAP SH*T UP!

Picture credits: http://www.flickr.com/photos/fil/144232588/

Page 77: ZF2 Modular Architecture - Taking advantage of it

index.php <?php

/**

* This makes our life easier when dealing with paths. Everything is

* relative to the application root now.

*/

chdir(dirname(__DIR__));

// Setup autoloading

require 'init_autoloader.php';

// Run the application!

Zend\Mvc\Application::init(require 'config/application.config.php')->run();

Page 78: ZF2 Modular Architecture - Taking advantage of it

index.php <?php

/**

* This makes our life easier when dealing with paths. Everything is

* relative to the application root now.

*/

chdir(dirname(__DIR__));

// Setup autoloading

require 'init_autoloader.php';

// Run the application!

Zend\Mvc\Application::init(require 'config/application.config.php')->run();

Page 79: ZF2 Modular Architecture - Taking advantage of it

config/application.config.php

79

return array(

'modules' => array(

'DoctrineModule',

'DoctrineORMModule',

'SpeckPaypal',

'Application',

),

),

...

Page 80: ZF2 Modular Architecture - Taking advantage of it

Module.php namespace Application;

use Zend\Mvc\ModuleRouteListener;

use Zend\Mvc\MvcEvent;

class Module

{

public function onBootstrap(MvcEvent $e)

{[…]}

public function getConfig() {

return include __DIR__ . '/config/module.config.php';

}

public function getAutoloaderConfig() {}

}

80

Page 81: ZF2 Modular Architecture - Taking advantage of it

Module configuration file // config/module.config.php

return array(

'router' => array(

'routes' => array(...)

),

'controllers' => array(...),

'service_manager' => array(...),

'view_manager' => array(...),

...

)

Page 82: ZF2 Modular Architecture - Taking advantage of it

Where’s module configuration?

82

Here!

Page 83: ZF2 Modular Architecture - Taking advantage of it

Controllers <?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;

use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController

{

public function indexAction()

{

$timestamp = time();

return new ViewModel(array(

'timestamp' => $timestamp

));

}

}

Page 84: ZF2 Modular Architecture - Taking advantage of it

Actions <?php

namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;

use Zend\View\Model\ViewModel;

class IndexController extends AbstractActionController

{

public function indexAction()

{

$timestamp = time();

return new ViewModel(array(

'timestamp' => $timestamp

));

}

}

Page 85: ZF2 Modular Architecture - Taking advantage of it

CONVENTION

OVER

CONFIGURATION

Picture credits: http://www.flickr.com/photos/29233640@N07/8412347937/

Page 86: ZF2 Modular Architecture - Taking advantage of it

This is for all modules

86

return array(

'modules' => array(

'DoctrineModule',

'DoctrineORMModule',

'SpeckPaypal',

'Application',

),

),

...

config/application.config.php

Page 87: ZF2 Modular Architecture - Taking advantage of it

87

Feature A

Controller

Views

PHP Classes

Routing

Configurations

Page 88: ZF2 Modular Architecture - Taking advantage of it

88

Feature A

Controller

Views

PHP Classes

Routing

Configurations

Feature B

Controller

Views

PHP Classes

Routing

Configurations

Feature C

Controller

Views

PHP Classes

Routing

Configurations

Page 89: ZF2 Modular Architecture - Taking advantage of it

89

Controller

Views

PHP Classes

Routing

Configurations

Controller

Views

PHP Classes

Routing

Configurations

Controller

Views

PHP Classes

Routing

Configurations

Modules are merged at runtime

Page 90: ZF2 Modular Architecture - Taking advantage of it

CONFIGURATION MERGE

Picture credits: http://www.flickr.com/photos/michelleundihrefotos/5970015736

Page 91: ZF2 Modular Architecture - Taking advantage of it

91

Controller

Views

Routing

Controller

Views

Routing

Controller

Views

Routing

Modules are merged at runtime

PHP Classes PHP Classes PHP Classes

Configurations

Page 92: ZF2 Modular Architecture - Taking advantage of it

We can override things… Views / Layouts

92

return array(

...

'view_manager' => array(

...

),

)

Page 93: ZF2 Modular Architecture - Taking advantage of it

We can override things… Views / Layouts Routing Rules

93

return array(

...

'router' => array(

...

),

)

Page 94: ZF2 Modular Architecture - Taking advantage of it

We can override things… Views / Layouts Routing Rules All Other Configuration Parameters

94

Page 95: ZF2 Modular Architecture - Taking advantage of it

We can override things… Views / Layouts Routing Rules All Other Configuration Parameters

95

Do NOT modify original 3° party

modules!

Page 96: ZF2 Modular Architecture - Taking advantage of it

Custom Configuration

96

Do not touch anything here!

MODULE.local.php

Page 97: ZF2 Modular Architecture - Taking advantage of it

97

Controller

Views

Routing

Controllers

Views

Routing

Controller

Views

Routing

Modules are merged at runtime

PHP Classes PHP Classes PHP Classes

Configurations Configurations Configurations

Page 98: ZF2 Modular Architecture - Taking advantage of it

This happens for all modules

98

return array(

'modules' => array(

'DoctrineModule',

'DoctrineORMModule',

'SpeckPaypal',

'Application',

),

),

...

config/application.config.php

Order is Important!

Page 99: ZF2 Modular Architecture - Taking advantage of it

LET’S LOOK AROUND FIRST! Picture credits: http://www.flickr.com/photos/billward/5626976800

Page 100: ZF2 Modular Architecture - Taking advantage of it

http://modules.zendframework.com/

100

Page 101: ZF2 Modular Architecture - Taking advantage of it

What about a contact form?

101

Page 102: ZF2 Modular Architecture - Taking advantage of it

What about a contact form?

102

Page 103: ZF2 Modular Architecture - Taking advantage of it

cd vendor

git clone

https://github.com/weierophinney/PhlyContact.git

103

Page 104: ZF2 Modular Architecture - Taking advantage of it

104

Here we go…

Page 105: ZF2 Modular Architecture - Taking advantage of it

application.config.php <?php

return array(

'modules' => array(

'PhlyContact',

'Application',

),

'module_listener_options' => array(

[…]

),

);

105

Page 106: ZF2 Modular Architecture - Taking advantage of it

application.config.php <?php

return array(

'modules' => array(

'PhlyContact',

'Application',

),

'module_listener_options' => array(

[…]

),

);

106

Page 107: ZF2 Modular Architecture - Taking advantage of it

107

Default Configuration

Page 108: ZF2 Modular Architecture - Taking advantage of it

PhlyContact/config/module.config.php <?php

return array(

'phly_contact' => array(

[…]

'message' => array(

'to' => array('EMAIL HERE' => 'NAME HERE',),

'sender' => array(

'address' => 'EMAIL HERE',

'name' => 'NAME HERE',

),

'from' => array('EMAIL HERE' => 'NAME HERE',),

),

[…]

),

108

Page 109: ZF2 Modular Architecture - Taking advantage of it

109

Remember: Do NOT modify files in here!

Page 110: ZF2 Modular Architecture - Taking advantage of it

110

DO create and use files herein instead

Page 111: ZF2 Modular Architecture - Taking advantage of it

In less than 2 minutes…

111

Page 112: ZF2 Modular Architecture - Taking advantage of it

BUILDING OUR OWN MODULES

Picture credits: http://www.flickr.com/photos/pullip_junk/6624713631

Page 113: ZF2 Modular Architecture - Taking advantage of it

SHARED RESOURCES

Picture credits: http://www.flickr.com/photos/nasahqphoto/5162244810

Page 114: ZF2 Modular Architecture - Taking advantage of it

Catalogue

114

Shopping Cart

Page 115: ZF2 Modular Architecture - Taking advantage of it

115

Product

Catalogue Shopping Cart

Where shall we put this?

- id - name - price

Page 116: ZF2 Modular Architecture - Taking advantage of it

Little Information Needed

116

Page 117: ZF2 Modular Architecture - Taking advantage of it

117

Shopping Cart

Product - id - name - price

Page 118: ZF2 Modular Architecture - Taking advantage of it

We need a bit more stuff here…

118

Page 119: ZF2 Modular Architecture - Taking advantage of it

Catalogue

119

Shopping Cart

Product - id - name - price

Product

- id - name - price - description - picturePath

Page 120: ZF2 Modular Architecture - Taking advantage of it

Catalogue

120

Shopping Cart

- description - picturePath - …

Product - id - name - price

Product - id - name - price

Page 121: ZF2 Modular Architecture - Taking advantage of it

121

- description - picturePath - …

Product - id - name - price

Catalogue

Shopping Cart

Page 122: ZF2 Modular Architecture - Taking advantage of it

/**

* Catalogue\Entity\Product

* ...

*/

class Product extends \Ecommerce\Entity\Cartproduct {}

Through extension

/**

* Catalogue\Entity\Product

* ...

*/

class Product implements \Ecommerce\Entity\CartproductInterface {}

Through Interfaces

Constraints

Page 123: ZF2 Modular Architecture - Taking advantage of it

How do I make this possible?

123

Page 124: ZF2 Modular Architecture - Taking advantage of it

SERVICE MANAGER

Picture credits: http://www.flickr.com/photos/urbanwoodswalker/4375401057/

Page 125: ZF2 Modular Architecture - Taking advantage of it

Service Locator

SL Product

Controller

ShoppingCart

Page 126: ZF2 Modular Architecture - Taking advantage of it

NOT THE REGISTRY

Page 127: ZF2 Modular Architecture - Taking advantage of it

In a Controller Factory <?php

public function createService(ServiceLocatorInterface $services){

$serviceLocator = $services->getServiceLocator();

$cartService = $serviceLocator->get('CartItem');

$controller = new CartController($cartService);

return $controller;

}

}

Page 128: ZF2 Modular Architecture - Taking advantage of it

Original Module Configuration /* Shopping Cart Module – module.config.php */

return array(

'router' => array(…),

'controllers' => array(…),

'service_manager' => array(

'invokables' => array(

'CartItem' => 'Cart\Service\CartItem',

),

'factories' => array(…)

)

);

Page 129: ZF2 Modular Architecture - Taking advantage of it

Module Configuration /* Shopping Cart Module – module.config.php */

return array(

'router' => array(…),

'controllers' => array(…),

'service_manager' => array(

'invokables' => array(

// 'CartItem' => 'Cart\Service\CartItem',

'CartItem' => 'Catalogue\Service\CatalogueItem',

),

'factories' => array(…)

)

);

Page 130: ZF2 Modular Architecture - Taking advantage of it

130

LSP in Action

Catalogue

Shopping Cart

Product - id - name - price

Product - id - name - price - description - picturePath

Page 131: ZF2 Modular Architecture - Taking advantage of it

131

Catalogue

Shopping Cart

Product - id - name - price - description - picturePath

Product - id - name - price - description - picturePath

Page 132: ZF2 Modular Architecture - Taking advantage of it

REUSE ENABLED

Picture credits: http://www.flickr.com/photos/89544908@N00/7877685112/

Page 133: ZF2 Modular Architecture - Taking advantage of it

REUSE ENABLED

EVEN IN THE LARGE

Picture credits: http://www.flickr.com/photos/89544908@N00/7877685112/

Page 134: ZF2 Modular Architecture - Taking advantage of it

134

Page 135: ZF2 Modular Architecture - Taking advantage of it

A re-usable piece of functionality that can be used to construct a more complex application.

135

Evan Coury - http://evan.pro/zf2-modules-talk.html

Back to definition

Page 136: ZF2 Modular Architecture - Taking advantage of it

A re-usable piece of functionality that can be used to construct a more complex application.

136

Evan Coury - http://evan.pro/zf2-modules-talk.html

Now I understand it better!

Page 137: ZF2 Modular Architecture - Taking advantage of it

I hope you too.

Stefano Maraspin @maraspin [email protected]

Page 138: ZF2 Modular Architecture - Taking advantage of it

QUESTIONS?

Picture credits: http://www.flickr.com/photos/hefhoover/3929261255/

Page 139: ZF2 Modular Architecture - Taking advantage of it

139

@maraspin

Page 140: ZF2 Modular Architecture - Taking advantage of it

140

http://www.mvlabs.it/

Page 141: ZF2 Modular Architecture - Taking advantage of it
Page 142: ZF2 Modular Architecture - Taking advantage of it

Stefano Maraspin @maraspin [email protected]

http://joind.in/talk/view/8655