Más contenido relacionado Similar a Il Pattern di Zend Framework 2 (20) Más de Zend by Rogue Wave Software (20) Il Pattern di Zend Framework 21. Zend Framework 2
presenta Enrico Zimuel (enrico@zend.com)
Senior Software Engineer, Zend Technologies
Zend Framework Core Team
© All rights reserved. Zend Technologies, Inc.
2. Sommario
● Breve storia del progetto Zend Framework
● Zend Framework 2.0
● I pre-requisiti di ZF 2
● Miglioramento delle performance
● Nuove funzionalità e design patterns
▶ Event Manager
▶ Dependency Injection
▶ Service Locator
© All rights reserved. Zend Technologies, Inc.
4. Breve storia di ZF
● October 2005: Annuncio del progetto
● March 2006: Prima versione (pulic review), 0.1.0
● Fall 2006: Riscrittura dell'MVC
● July 2007: Prima release stabile 1.0
● March 2008: Prima minor release 1.5.0
▶ Zend_Form, Zend_Layout
● September 2008: 1.6.0
▶ Integrazione con Dojo, PHPUnit scaffolding
● November 2008: 1.7.0
▶ Supporto AMF, miglioramento delle performance
© All rights reserved. Zend Technologies, Inc.
5. Breve storia di ZF (2)
● April 2009: 1.8.0
▶ Zend_Tool, Zend_Application
● August 2009: 1.9.0
▶ Aggiunta di Zend_Feed_Reader
▶ Supporto di PHP 5.3
● January 2010: 1.10.0
▶ Aggiunta di Zend_Feed_Writer, refactoring di Zend_Feed
▶ Cambio della documentazione: adozione di PhD per la
generazione del manuale utente, aggiunta dei commenti,
nuova sezione “Learning Zend Framework section”
● November 2010: 1.11.0
▶ Supporto dispositivi mobile tramiteZend_Http_UserAgent
▶ Simple Cloud API tramite Zend_Cloud
© All rights reserved. Zend Technologies, Inc.
7. Zend Framework 2.0
● Nuova major release
▶ Ci ha permesso di non dover tener conto
della retro-compatibilità
▶ Prerequisiti: PHP 5.3 e superiore
● Attenzione posta su:
▶ Consistenza
▶ Performance
▶ Documentazione
▶ Produttività utente
© All rights reserved. Zend Technologies, Inc.
8. Primi passi verso ZF 2.0
● Conversione del codice da prefissi gestiti a
mano (es. “Zend_Foo”) ai namespace nativi
di PHP 5.3
● Refactoring delle Eccezioni
● Cambio di ZF per essere solo autoload
● Miglioramento e standardizzazione del sistema
di plugin
© All rights reserved. Zend Technologies, Inc.
9. ZF 2.0 (dev3)
● Il 14 giugno è stata rilasciata la versione dev3
di Zend Framework 2.0
● Tra le funzionalità già implementate:
▶ Refactoring di ZendTool e CodeGenerator
▶ Migrazione e refactoring dei servizi LiveDocx
▶ EventManager
▶ Dependency Injection
● Maggiori info: http://bit.ly/lptIpN
© All rights reserved. Zend Technologies, Inc.
11. ZF2 in una slide
● Miglioramenti:
▶ Namespace (supporto nativo di PHP)
▶ Exception
▶ Autoloading
▶ MVC
▶ Plugin
▶ Documentazione
▶ Performance
● Nuove funzionalità:
▶ Event Manager
▶ Dependency Injection / Service Locator
▶ Supporto di nuovi servizi cloud
▶ Molto altro ancora...
© All rights reserved. Zend Technologies, Inc.
12. Namespace
© All rights reserved. Zend Technologies, Inc.
13. L'approccio di ZF2 ai namespace
● Formalizzare i prefissi utilizzati in ZF1
▶ Separatore di namespace correllato con il
separatore di directory
● Aiutare ad identificare le dipendenze (imports)
▶ Abilitare il refactoring utilizzazando diverse
implementazioni
▶ Facilitare il sistema di packaging
© All rights reserved. Zend Technologies, Inc.
14. Namespace
namespace ZendEventManager;
namespace ZendEventManager;
use ZendStdlibCallbackHandler;
use ZendStdlibCallbackHandler;
class EventManager implements EventCollection
class EventManager implements EventCollection
{{
/* ... */
/* ... */
}}
© All rights reserved. Zend Technologies, Inc.
15. Namespace
● Interfacce come namespace
▶ I nomi d'interfaccia sono aggettivi o
sostantivi
▶ Implementazione concreta in sub-
namespace denominati dopo
l'interfaccia
▶ Paradigma Contract-Oriented
© All rights reserved. Zend Technologies, Inc.
16. Interfacce come Namespace
Zend/Session namespace ZendSession;
namespace ZendSession;
|-- Storage.php interface Storage
interface Storage
`-- Storage {{
|-- ArrayStorage.php /* ... */
/* ... */
`-- SessionStorage.php }}
namespace ZendSessionStorage;
namespace ZendSessionStorage;
use ArrayObject,
use ArrayObject,
ZendSessionStorage,
ZendSessionStorage,
ZendSessionException;
ZendSessionException;
class ArrayStorage
class ArrayStorage
extends ArrayObject
extends ArrayObject
implements Storage
implements Storage
{ /* ... */ }
{ /* ... */ }
© All rights reserved. Zend Technologies, Inc.
17. ZF2 approccio ai namespace
● Ogni file di classe dichiara un namespace
● Un namespace per file
● Ogniclasse utilizzata che non fa parte del
namespace attuale è importata (tipicamante
tramite un alias)
● L'uso di riferimenti globali di classe è scoraggiato,
eccetto nel caso di classi referenziate tramite
stringhe
© All rights reserved. Zend Technologies, Inc.
19. ZF2 Autoloading
● Non più chiamate require_once!
● Differenti approcci:
▶ Stile ZF1 con include_path autoloader
▶ Per-namespace/prefix autoloading
▶ Class-map autoloading
© All rights reserved. Zend Technologies, Inc.
20. Stile ZF1 di autoloading
require_once 'Zend/Loader/StandardAutoloader.php';
require_once 'Zend/Loader/StandardAutoloader.php';
$loader =
$loader =
new ZendLoaderStandardAutoloader(array(
new ZendLoaderStandardAutoloader(array(
'fallback_autoloader' => true,
'fallback_autoloader' => true,
));
));
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
21. ZF2 NS/Prefix Autoloading
require_once 'Zend/Loader/StandardAutoloader.php';
require_once 'Zend/Loader/StandardAutoloader.php';
$loader = new ZendLoaderStandardAutoloader();
$loader = new ZendLoaderStandardAutoloader();
$loader->registerNamespace(
$loader->registerNamespace(
'My', __DIR__ . '/../library/My')
'My', __DIR__ . '/../library/My')
->registerPrefix(
->registerPrefix(
'Phly_', __DIR__ . '/../library/Phly');
'Phly_', __DIR__ . '/../library/Phly');
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
22. ZF2 Class-Map Autoloading
● .classmap.php:
return array(
return array(
'MyFooBar' => __DIR__ . '/Foo/Bar.php',
'MyFooBar' => __DIR__ . '/Foo/Bar.php',
);
);
require_once 'Zend/Loader/ClassMapAutoloader.php';
require_once 'Zend/Loader/ClassMapAutoloader.php';
$loader = new ZendLoaderClassMapAutoloader();
$loader = new ZendLoaderClassMapAutoloader();
$loader->registerAutoloadMap(
$loader->registerAutoloadMap(
__DIR__ . '/../library/.classmap.php');
__DIR__ . '/../library/.classmap.php');
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
23. Class-Maps richiede più lavoro?
● Si, ma abbiamo già rilasciato un tool a linea di
comando: bin/classmap_generator.php
● L'utilizzo è immediato:
$ cd your/library
$ cd your/library
$ php /path/to/classmap_generator.php -w
$ php /path/to/classmap_generator.php -w
● Class-Map verrà creato in .classmap.php
© All rights reserved. Zend Technologies, Inc.
24. Perchè?
● Class-Maps evidenzia un miglioramento di
performance del 25% rispetto all'autoloader
del ZF1 (senza acceleratore di opcode)
▶ e un miglioramento del 60-85% con un
acceleratore di bytecode PHP
● L'utilizzo di prefissi e namespace con percorsi
specifici evidenzia un miglioramento del 10%
sulle performance (senza acceleratore di
opcode)
▶ e un miglioramento del 40% con un
acceleratore di bytecode PHP
© All rights reserved. Zend Technologies, Inc.
25. Strategie di autoloading
● Con strategie di autoloading differenti c'è la
necessità di un factory
● Scegliere tra differenti strategie:
▶ Class-Map per performance migliori
▶ Prefissi/Namespace per esigenze standard
▶ Autoloader “classico” (in stile ZF1) per
ambienti di sviluppo
© All rights reserved. Zend Technologies, Inc.
26. Migrare a ZF2
● Potete utilizzare il nuovo autoloader ZF2 da
subito, anche per progetti ZF1
● Iniziare a migrare ora!
● “Backported ZF2 Autoloaders”
by Matthew Weier O'Phinney
http://bit.ly/mq4UAh
© All rights reserved. Zend Technologies, Inc.
27. Exception
27 © All rights reserved. Zend Technologies, Inc.
28. Problema
● Tutte le eccezioni derivano da una classe
comune
● Nessuna possibilità di espandere la
semantica delle eccezioni tramite SPL
© All rights reserved. Zend Technologies, Inc.
29. L'approccio di ZF2
● Eliminare Zend_Exception
● Ogni componente definisce una propria
interfaccia di eccezioni
● Eccezioni addizionali vengono create in
un subnamespace specifico
▶ Queste eccezioni estendono le funzionalità
SPL ed implementato le interfacce
specifiche dei componenti
© All rights reserved. Zend Technologies, Inc.
30. Vantaggi
● Intercetttare specifiche eccezioni
● Intercettare eccezioni di tipo SPL
● Intercettare eccezioni a livello di
componenti
● Intercettare basandosi su un tipo di
eccezione globale
© All rights reserved. Zend Technologies, Inc.
31. Esempio di Exception
Zend/EventManager
Zend/EventManager namespace
namespace
|-- Exception.php
|-- Exception.php ZendEventManager;
ZendEventManager;
`-- Exception
`-- Exception
`-- InvalidArgument-
`-- InvalidArgument- interface Exception {}
interface Exception {}
Exception.php
Exception.php
namespace ZendEventManagerException;
namespace ZendEventManagerException;
use ZendEventManagerException;
use ZendEventManagerException;
class InvalidArgumentException
class InvalidArgumentException
extends InvalidArgumentException
extends InvalidArgumentException
implements Exception
implements Exception
{}
{}
© All rights reserved. Zend Technologies, Inc.
32. Esempio di Exception (2)
namespace ZendEventManagerException;
namespace ZendEventManagerException;
use ZendEventManagerException;
use ZendEventManagerException;
try {
try {
$events->trigger('foo.bar', $object);
$events->trigger('foo.bar', $object);
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $e) {
} catch (Exception $e) {
} catch (Exception $e) {
} catch (InvalidArgumentException $e) {
} catch (InvalidArgumentException $e) {
} catch (Exception $e) {
} catch (Exception $e) {
}}
© All rights reserved. Zend Technologies, Inc.
34. Nuove funzionalità
● ZendEventManager
● ZendDi
● Nuovi servizi cloud:
▶ ZendRackspace
▶ ZendServiceGoGrid
▶ ZendCloudInfrastructure
● Amazon S3
● Rackspace
● GoGrid
● E molto altro...
© All rights reserved. Zend Technologies, Inc.
36. Il problema
● Come inserire sistemi di logging/debug in un progetto Zend
Framework?
● Come offrire la possibilità di utilizzare un sistema di caching
senza estendere il codice del framework?
● Come offrire la possibilità di validare, filtrare, gestire un ACL,
etc, senza estendere il codice del framework?
● Come offrire la possibilità di decidere l'ordine di un plugin, di
intercettare un filtro, un evento, un trigger, etc?
● Come offrire uno strumento in grado di soddisfare queste
esigenze?
© All rights reserved. Zend Technologies, Inc.
37. ZF2 Event Manager
● Summa di diversi design patterns: PubSub,
SignalSlot, ed Intercepting Filters
● Non risolvono completamente il problema di
composizione/statici
▶ Possiamo risolverlo in PHP 5.4 via Traits
▶ Ci sono alcuni modi eleganti per gestire
componenti statici
© All rights reserved. Zend Technologies, Inc.
38. Interfaccia EventCollection
namespace ZendEventManager;
namespace ZendEventManager;
use ZendStdlibCallbackHandler;
use ZendStdlibCallbackHandler;
interface EventCollection
interface EventCollection
{{
public function trigger($event, $context, $argv == array());
public function trigger($event, $context, $argv array());
public function triggerUntil($event, $context, $argv, $callback);
public function triggerUntil($event, $context, $argv, $callback);
public function attach($event, $callback, $priority == 1);
public function attach($event, $callback, $priority 1);
public function detach(CallbackHandler $handle);
public function detach(CallbackHandler $handle);
public function getEvents();
public function getEvents();
public function getHandlers($event);
public function getHandlers($event);
public function clearHandlers($event);
public function clearHandlers($event);
}}
© All rights reserved. Zend Technologies, Inc.
39. Triggering di eventi
use ZendEventManagerEventManager;
use ZendEventManagerEventManager;
$events = new EventManager();
$events = new EventManager();
$events->trigger($eventName, $object, $params);
$events->trigger($eventName, $object, $params);
● Dove:
▶ $eventName è il nome dell'evento, di solito il nome
del metod
▶ $object è l'oggetto triggering dell'evento
▶ $params sono i parametri di cui l'handler
necessita, di solito gli argomenti del
metodo
© All rights reserved. Zend Technologies, Inc.
40. CallbackHandler
$handler = $events->attach(’some-event’,
$handler = $events->attach(’some-event’,
function($e) use ($log) {
function($e) use ($log) {
$event = $e->getName();
$event = $e->getName();
$context = get_class($e->getTarget());
$context = get_class($e->getTarget());
$params = json_encode($e->getParams());
$params = json_encode($e->getParams());
$log->info(sprintf("%s: %s: %s", $event,
$log->info(sprintf("%s: %s: %s", $event,
$context, $params));
$context, $params));
});
});
© All rights reserved. Zend Technologies, Inc.
41. Comporre un Event Manager
use ZendEventManagerEventCollection as Events,
use ZendEventManagerEventCollection as Events,
ZendEventManagerEventManager;
ZendEventManagerEventManager;
class Foo
class Foo
{{
protected $events;
protected $events;
public function events(Events $events == null) {{
public function events(Events $events null)
if (null !== $events) {{
if (null !== $events)
$this->events == $events;
$this->events $events;
}} elseif (null === $this->events) {{
elseif (null === $this->events)
$this->events == new EventManager(__CLASS__);
$this->events new EventManager(__CLASS__);
}}
return $this->events;
return $this->events;
}}
public function doSomething($param1, $param2) {{
public function doSomething($param1, $param2)
$params == compact('param1', 'param2');
$params compact('param1', 'param2');
$this->events()->trigger(__FUNCTION__, $this, $params);
$this->events()->trigger(__FUNCTION__, $this, $params);
}}
}}
© All rights reserved. Zend Technologies, Inc.
42. Utilizzo dei Trait!
use ZendEventManagerEventCollection as Events,
use ZendEventManagerEventCollection as Events,
ZendEventManagerEventManager;
ZendEventManagerEventManager;
trait Eventful
trait Eventful
{{
public function events(Events $events == null) {{
public function events(Events $events null)
if (null !== $events) {{
if (null !== $events)
$this->events == $events;
$this->events $events;
}} elseif (null === $this->events) {{
elseif (null === $this->events)
$this->events == new EventManager(__CLASS__);
$this->events new EventManager(__CLASS__);
}}
return $this->events;
return $this->events;
}}
}}
class Foo
class Foo
{{
use Eventful;
use Eventful;
protected $events;
protected $events;
}}
© All rights reserved. Zend Technologies, Inc.
44. Il problema
● Come gestire le dipendeze tra oggetti?
▶ In particolare, come gestire le dipendenze
tra Controller?
© All rights reserved. Zend Technologies, Inc.
45. L'approccio di ZF2
● Service Locator
▶ Schema di base:
● set($name, $service)
● get($name)
▶ Formalizzazione dell'application service
(mailer, logger, profiler, etc.)
▶ Buone interfacce con il typehinting
© All rights reserved. Zend Technologies, Inc.
46. Service Locator
use ZendDiServiceLocator,
use ZendDiServiceLocator,
ZendEventManagerEventManager;
ZendEventManagerEventManager;
class MyLocator extends ServiceLocator
class MyLocator extends ServiceLocator
{{
protected $events;
protected $events;
protected $map == array('events' => 'getEvents');
protected $map array('events' => 'getEvents');
public function getEvents()
public function getEvents()
{{
if (null !== $this->events) {{
if (null !== $this->events)
return $this->events;
return $this->events;
}}
$this->events == new EventManager();
$this->events new EventManager();
return $this->events;
return $this->events;
}}
}}
© All rights reserved. Zend Technologies, Inc.
47. L'approccio di ZF2
● Dependency Injection Container
▶ Injection in costruzione (construct) e
setters
▶ Via codice o tramite configurazione
▶ Tipicamente utilizzato per iniettare un
service locator
© All rights reserved. Zend Technologies, Inc.
48. Dependency Injection
$db == new Definition('MyDbAdapterSqlite');
$db new Definition('MyDbAdapterSqlite');
$db->setParam('name', __DIR__ .. '/../data/db/users.db');
$db->setParam('name', __DIR__ '/../data/db/users.db');
$mapper == new Definition('MyMapperDb');
$mapper new Definition('MyMapperDb');
$mapper->addMethodCall(
$mapper->addMethodCall(
'setAdapter', array(new Reference('db')));
'setAdapter', array(new Reference('db')));
$service == new Definition('MyResourceUsers');
$service new Definition('MyResourceUsers');
$service->setParam('mapper', new Reference('mapper'));
$service->setParam('mapper', new Reference('mapper'));
$di == new DependencyInjector;
$di new DependencyInjector;
$di->setDefinitions(array(
$di->setDefinitions(array(
'db'
'db' => $db,
=> $db,
'mapper' => $mapper,
'mapper' => $mapper,
'users' => $service,
'users' => $service,
));
));
$users == $di->get('users'); // MyResourceUsers
$users $di->get('users'); // MyResourceUsers
© All rights reserved. Zend Technologies, Inc.
49. Controller come servizi
● Risolve il problema della dipendenza dei
controller
● Ogni richiesta istanzia soltanto lo stretto
necessario
● Migliore testabilità dei controller
© All rights reserved. Zend Technologies, Inc.
50. Controller come servizi: esempio
$userController == new Definition('SiteControllerUser');
$userController new Definition('SiteControllerUser');
$userController->setParam('service',
$userController->setParam('service',
new Reference('users'));
new Reference('users'));
$di->setDefinition($userController, 'controller-user');
$di->setDefinition($userController, 'controller-user');
// Inside dispatcher:
// Inside dispatcher:
$controller == $di->get($controllerName);
$controller $di->get($controllerName);
$result == $controller->dispatch($request, $response);
$result $controller->dispatch($request, $response);
© All rights reserved. Zend Technologies, Inc.
52. ZendCloud
● Supporto di nuovi servizi cloud:
▶ Rackspace
▶ GoGrid
● Supporto di Rackspace in
ZendCloudStorageService
▶ Rackspace
● ZendCloudInfrastructure per la gestione delle
infrastrutture di cloud computing:
▶ Amazon EC2
▶ Rackspace Cloud Servers
▶ GoGrid
▶ Windows Azure
© All rights reserved. Zend Technologies, Inc.
53. ZendCloudInfrastructure
● ZendCloudInfrastructure (alpha version):
▶ Attualmente supporta soltanto Amazon EC2
▶ A breve disponibili adapter per Rackspace
Servers e GoGrid
▶ Download: http://bit.ly/imQLzB
● ZendServiceRackspaceFiles (beta version):
▶ Download: http://bit.ly/muC6AT
© All rights reserved. Zend Technologies, Inc.
55. Contribuire a ZF2
● ZF2 wiki:
▶ http://bit.ly/zf2wiki
● zf-contributors mailing list:
▶ zf-contributors-subscribe@lists.zend.com
● IRC:
▶ #zftalk.dev su Freenode
© All rights reserved. Zend Technologies, Inc.
56. Risorse
● Git guide:
▶ http://bit.ly/zf2gitguide
● GitHub:
▶ http://github.com/zendframework/zf2
● Official repo:
▶ git://git.zendframework.com/zf.git
▶ http://git.zendframework.com/
© All rights reserved. Zend Technologies, Inc.
57. Domande?
© All rights reserved. Zend Technologies, Inc.