Zend Framework 2

Transcript

Zend Framework 2
Zend Framework 2
presenta Enrico Zimuel ([email protected])
Senior Software Engineer, Zend Technologies
Zend Framework Core Team
© All rights reserved. Zend Technologies, Inc.
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.
Zend Framework
© All rights reserved. Zend Technologies, Inc.
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
▶
●
September 2008: 1.6.0
▶
●
Zend_Form, Zend_Layout
Integrazione con Dojo, PHPUnit scaffolding
November 2008: 1.7.0
▶
Supporto AMF, miglioramento delle performance
© All rights reserved. Zend Technologies, Inc.
Breve storia di ZF (2)
●
April 2009: 1.8.0
▶
●
●
August 2009: 1.9.0
▶
Aggiunta di Zend_Feed_Reader
▶
Supporto di PHP 5.3
January 2010: 1.10.0
▶
▶
●
Zend_Tool, Zend_Application
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.
© All rights reserved. Zend Technologies, Inc.
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.
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.
ZF 2.0 (dev3)
●
●
●
Il 14 giugno è stata rilasciata la versione dev3
di Zend Framework 2.0
Tra le funzionalità già implementate:
▶
Refactoring di Zend\Tool e CodeGenerator
▶
Migrazione e refactoring dei servizi LiveDocx
▶
EventManager
▶
Dependency Injection
Maggiori info: http://bit.ly/lptIpN
© All rights reserved. Zend Technologies, Inc.
“Riscrivere il codice
solo se ha senso”
© All rights reserved. Zend Technologies, Inc.
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.
Namespace
© All rights reserved. Zend Technologies, Inc.
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.
Namespace
namespace
namespace Zend\EventManager;
Zend\EventManager;
use
use Zend\Stdlib\CallbackHandler;
Zend\Stdlib\CallbackHandler;
class
class EventManager
EventManager implements
implements EventCollection
EventCollection
{{
/*
/* ...
... */
*/
}}
© All rights reserved. Zend Technologies, Inc.
Namespace
●
Interfacce come namespace
▶
▶
▶
I nomi d'interfaccia sono aggettivi o
sostantivi
Implementazione concreta in subnamespace denominati dopo
l'interfaccia
Paradigma Contract-Oriented
© All rights reserved. Zend Technologies, Inc.
Interfacce come Namespace
Zend/Session
|-- Storage.php
`-- Storage
|-- ArrayStorage.php
`-- SessionStorage.php
namespace
namespace Zend\Session;
Zend\Session;
interface
interface Storage
Storage
{{
/*
/* ...
... */
*/
}}
namespace
namespace Zend\Session\Storage;
Zend\Session\Storage;
use
use ArrayObject,
ArrayObject,
Zend\Session\Storage,
Zend\Session\Storage,
Zend\Session\Exception;
Zend\Session\Exception;
class
class ArrayStorage
ArrayStorage
extends
extends ArrayObject
ArrayObject
implements
implements Storage
Storage
{{ /*
/* ...
... */
*/ }}
© All rights reserved. Zend Technologies, Inc.
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.
Autoloading
© All rights reserved. Zend Technologies, Inc.
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.
Stile ZF1 di autoloading
require_once
require_once 'Zend/Loader/StandardAutoloader.php';
'Zend/Loader/StandardAutoloader.php';
$loader
$loader ==
new
new Zend\Loader\StandardAutoloader(array(
Zend\Loader\StandardAutoloader(array(
'fallback_autoloader'
'fallback_autoloader' =>
=> true,
true,
));
));
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
ZF2 NS/Prefix Autoloading
require_once
require_once 'Zend/Loader/StandardAutoloader.php';
'Zend/Loader/StandardAutoloader.php';
$loader
$loader == new
new Zend\Loader\StandardAutoloader();
Zend\Loader\StandardAutoloader();
$loader->registerNamespace(
$loader->registerNamespace(
'My',
'My', __DIR__
__DIR__ .. '/../library/My')
'/../library/My')
->registerPrefix(
->registerPrefix(
'Phly_',
'Phly_', __DIR__
__DIR__ .. '/../library/Phly');
'/../library/Phly');
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
ZF2 Class-Map Autoloading
●
.classmap.php:
return
return array(
array(
'My\Foo\Bar'
'My\Foo\Bar' =>
=> __DIR__
__DIR__ .. '/Foo/Bar.php',
'/Foo/Bar.php',
);
);
require_once
require_once 'Zend/Loader/ClassMapAutoloader.php';
'Zend/Loader/ClassMapAutoloader.php';
$loader
$loader == new
new Zend\Loader\ClassMapAutoloader();
Zend\Loader\ClassMapAutoloader();
$loader->registerAutoloadMap(
$loader->registerAutoloadMap(
__DIR__
__DIR__ .. '/../library/.classmap.php');
'/../library/.classmap.php');
$loader->register();
$loader->register();
© All rights reserved. Zend Technologies, Inc.
Class-Maps richiede più lavoro?
●
●
Si, ma abbiamo già rilasciato un tool a linea di
comando: bin/classmap_generator.php
L'utilizzo è immediato:
$$ cd
cd your/library
your/library
$$ php
php /path/to/classmap_generator.php
/path/to/classmap_generator.php -w
-w
●
Class-Map verrà creato in .classmap.php
© All rights reserved. Zend Technologies, Inc.
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.
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.
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.
Exception
27
© All rights reserved. Zend Technologies, Inc.
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.
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.
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.
Esempio di Exception
Zend/EventManager
Zend/EventManager
|-|-- Exception.php
Exception.php
`-`-- Exception
Exception
`-`-- InvalidArgumentInvalidArgumentException.php
Exception.php
namespace
namespace
Zend\EventManager;
Zend\EventManager;
interface
interface Exception
Exception {}
{}
namespace
namespace Zend\EventManager\Exception;
Zend\EventManager\Exception;
use
use Zend\EventManager\Exception;
Zend\EventManager\Exception;
class
class InvalidArgumentException
InvalidArgumentException
extends
extends \InvalidArgumentException
\InvalidArgumentException
implements
implements Exception
Exception
{}
{}
© All rights reserved. Zend Technologies, Inc.
Esempio di Exception (2)
namespace
namespace Zend\EventManager\Exception;
Zend\EventManager\Exception;
use
use Zend\EventManager\Exception;
Zend\EventManager\Exception;
try
try {{
$events->trigger('foo.bar',
$events->trigger('foo.bar', $object);
$object);
}} catch
catch (InvalidArgumentException
(InvalidArgumentException $e)
$e) {{
}} catch
catch (Exception
(Exception $e)
$e) {{
}} catch
catch (\InvalidArgumentException
(\InvalidArgumentException $e)
$e) {{
}} catch
catch (\Exception
(\Exception $e)
$e) {{
}}
© All rights reserved. Zend Technologies, Inc.
Nuove funzionalità
33
© All rights reserved. Zend Technologies, Inc.
Nuove funzionalità
●
Zend\EventManager
●
Zend\Di
●
Nuovi servizi cloud:
●
▶
Zend\Rackspace
▶
Zend\Service\GoGrid
▶
Zend\Cloud\Infrastructure
●
Amazon S3
●
Rackspace
●
GoGrid
E molto altro...
© All rights reserved. Zend Technologies, Inc.
Event manager
35
© All rights reserved. Zend Technologies, Inc.
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.
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.
Interfaccia EventCollection
namespace
namespace Zend\EventManager;
Zend\EventManager;
use
Zend\Stdlib\CallbackHandler;
use Zend\Stdlib\CallbackHandler;
interface
interface EventCollection
EventCollection
{{
public
public function
function trigger($event,
trigger($event, $context,
$context, $argv
$argv == array());
array());
public
function
triggerUntil($event,
$context,
$argv,
public function triggerUntil($event, $context, $argv, $callback);
$callback);
public
function
attach($event,
$callback,
$priority
=
1);
public function attach($event, $callback, $priority = 1);
public
public function
function detach(CallbackHandler
detach(CallbackHandler $handle);
$handle);
public
public function
function getEvents();
getEvents();
public
function
getHandlers($event);
public function getHandlers($event);
public
public function
function clearHandlers($event);
clearHandlers($event);
}}
© All rights reserved. Zend Technologies, Inc.
Triggering di eventi
use
use Zend\EventManager\EventManager;
Zend\EventManager\EventManager;
$events
$events == new
new EventManager();
EventManager();
$events->trigger($eventName,
$events->trigger($eventName, $object,
$object, $params);
$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.
CallbackHandler
$handler
$handler == $events->attach(’some-event’,
$events->attach(’some-event’,
function($e)
function($e) use
use ($log)
($log) {{
$event
$event == $e->getName();
$e->getName();
$context
$context == get_class($e->getTarget());
get_class($e->getTarget());
$params
$params == json_encode($e->getParams());
json_encode($e->getParams());
$log->info(sprintf("%s:
$log->info(sprintf("%s: %s:
%s: %s",
%s", $event,
$event,
$context,
$context, $params));
$params));
});
});
© All rights reserved. Zend Technologies, Inc.
Comporre un Event Manager
use
use Zend\EventManager\EventCollection
Zend\EventManager\EventCollection as
as Events,
Events,
Zend\EventManager\EventManager;
Zend\EventManager\EventManager;
class
class Foo
Foo
{{
protected
protected $events;
$events;
public
function
public function events(Events
events(Events $events
$events == null)
null) {{
if
if (null
(null !==
!== $events)
$events) {{
$this->events
$this->events == $events;
$events;
}} elseif
(null
===
$this->events)
elseif (null === $this->events) {{
$this->events
$this->events == new
new EventManager(__CLASS__);
EventManager(__CLASS__);
}}
return
return $this->events;
$this->events;
}}
public
public function
function doSomething($param1,
doSomething($param1, $param2)
$param2) {{
$params
$params == compact('param1',
compact('param1', 'param2');
'param2');
$this->events()->trigger(__FUNCTION__,
$this->events()->trigger(__FUNCTION__, $this,
$this, $params);
$params);
}}
}}
© All rights reserved. Zend Technologies, Inc.
Utilizzo dei Trait!
use
use Zend\EventManager\EventCollection
Zend\EventManager\EventCollection as
as Events,
Events,
Zend\EventManager\EventManager;
Zend\EventManager\EventManager;
trait
trait Eventful
Eventful
{{
public
public function
function events(Events
events(Events $events
$events == null)
null) {{
if
if (null
(null !==
!== $events)
$events) {{
$this->events
$this->events == $events;
$events;
}} elseif
(null
===
$this->events)
elseif (null === $this->events) {{
$this->events
$this->events == new
new EventManager(__CLASS__);
EventManager(__CLASS__);
}}
return
return $this->events;
$this->events;
}}
}}
class
class Foo
Foo
{{
use
use Eventful;
Eventful;
protected
protected $events;
$events;
}}
© All rights reserved. Zend Technologies, Inc.
Dependency Injection
43
© All rights reserved. Zend Technologies, Inc.
Il problema
●
Come gestire le dipendeze tra oggetti?
▶
In particolare, come gestire le dipendenze
tra Controller?
© All rights reserved. Zend Technologies, Inc.
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.
Service Locator
use
use Zend\Di\ServiceLocator,
Zend\Di\ServiceLocator,
Zend\EventManager\EventManager;
Zend\EventManager\EventManager;
class
class MyLocator
MyLocator extends
extends ServiceLocator
ServiceLocator
{{
protected
protected $events;
$events;
protected
$map
protected $map == array('events'
array('events' =>
=> 'getEvents');
'getEvents');
}}
public
public function
function getEvents()
getEvents()
{{
if
if (null
(null !==
!== $this->events)
$this->events) {{
return
return $this->events;
$this->events;
}}
$this->events
$this->events == new
new EventManager();
EventManager();
return
return $this->events;
$this->events;
}}
© All rights reserved. Zend Technologies, Inc.
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.
Dependency Injection
$db
$db == new
new Definition('My\Db\Adapter\Sqlite');
Definition('My\Db\Adapter\Sqlite');
$db->setParam('name',
$db->setParam('name', __DIR__
__DIR__ .. '/../data/db/users.db');
'/../data/db/users.db');
$mapper
$mapper == new
new Definition('My\Mapper\Db');
Definition('My\Mapper\Db');
$mapper->addMethodCall(
$mapper->addMethodCall(
'setAdapter',
'setAdapter', array(new
array(new Reference('db')));
Reference('db')));
$service
$service == new
new Definition('My\Resource\Users');
Definition('My\Resource\Users');
$service->setParam('mapper',
$service->setParam('mapper', new
new Reference('mapper'));
Reference('mapper'));
$di
$di == new
new DependencyInjector;
DependencyInjector;
$di->setDefinitions(array(
$di->setDefinitions(array(
'db'
=>
'db'
=> $db,
$db,
'mapper'
'mapper' =>
=> $mapper,
$mapper,
'users'
'users' =>
=> $service,
$service,
));
));
$users
$users == $di->get('users');
$di->get('users'); //
// My\Resource\Users
My\Resource\Users
© All rights reserved. Zend Technologies, Inc.
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.
Controller come servizi: esempio
$userController
$userController == new
new Definition('Site\Controller\User');
Definition('Site\Controller\User');
$userController->setParam('service',
$userController->setParam('service',
new
new Reference('users'));
Reference('users'));
$di->setDefinition($userController,
$di->setDefinition($userController, 'controller-user');
'controller-user');
//
// Inside
Inside dispatcher:
dispatcher:
$controller
$controller == $di->get($controllerName);
$di->get($controllerName);
$result
=
$controller->dispatch($request,
$result = $controller->dispatch($request, $response);
$response);
© All rights reserved. Zend Technologies, Inc.
Nuovi servizi cloud
51
© All rights reserved. Zend Technologies, Inc.
Zend\Cloud
●
Supporto di nuovi servizi cloud:
▶
▶
●
Supporto di Rackspace in
Zend\Cloud\StorageService
▶
●
Rackspace
GoGrid
Rackspace
Zend\Cloud\Infrastructure per la gestione delle
infrastrutture di cloud computing:
▶
▶
▶
▶
Amazon EC2
Rackspace Cloud Servers
GoGrid
Windows Azure
© All rights reserved. Zend Technologies, Inc.
Zend\Cloud\Infrastructure
●
Zend\Cloud\Infrastructure (alpha version):
▶
▶
▶
●
Attualmente supporta soltanto Amazon EC2
A breve disponibili adapter per Rackspace
Servers e GoGrid
Download: http://bit.ly/imQLzB
Zend\Service\Rackspace\Files (beta version):
▶
Download: http://bit.ly/muC6AT
© All rights reserved. Zend Technologies, Inc.
Partecipare al progetto
54
© All rights reserved. Zend Technologies, Inc.
Contribuire a ZF2
●
ZF2 wiki:
▶
●
zf-contributors mailing list:
▶
●
http://bit.ly/zf2wiki
[email protected]
IRC:
▶
#zftalk.dev su Freenode
© All rights reserved. Zend Technologies, Inc.
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.
Domande?
© All rights reserved. Zend Technologies, Inc.
Grazie!
Maggiori informazioni:
http://www.zend.com
http://framework.zend.com/
© All rights reserved. Zend Technologies, Inc.