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.