Existe uma coisa que um programador PHPnão pode ter...                            MEDO!
Advertência   Alguns exemplos de código são exemplos de    como implementar construções com Zend    Framework 2 e não do ...
Advertência   Esta apresentação não visa saciar sua sede de    conhecimento, mas deixar você sedento por    ele.
O que esperar do Zend Framework 2  Flávio Gomes da  Silva Lisboa www.fgsl.eti.br                    @fgsl
Inspirador   Inspirado                                    Desde 2008 capacitando                                    profis...
Uma Breve História do ZF      Flávio Gomes da Silva Lisboa
A Gênese   Outubro de 2005: o projeto é anunciado   Março de 2006: primeiro release público,    0.1.0   Final de 2006: ...
1.0.0, julho de 2007   Primeiro release estável   Sistema básico de MVC,    com plugins, action helpers,    renderização...
1.5.0 – Março de 2008   Primeiro release menor   Zend_Form   Zend_Layout   Sistema de view helper ciente    do layout ...
1.6.0 – Setembro de 2008   Integração com Dojo   Zend_Test: extensão PHPUnit    para controladores   Action helper Cont...
1.7.0 – Novembro de 2008   Suporte à AMF   Melhorias de performance
1.8.0 – Abril de 2009   Zend_Tool   Zend_Application                            AMPLAMENTE                              ...
1.9.0 – Agosto de 2009   Zend_Feed_Reader   Suporte/compatibilidade    com PHP 5.3   Adições levadas pela    comunidade...
1.10.0 – Janeiro de 2009   Integração de    ControllerTestCase com    Zend_Application   Adição de Zend_Feed_Writer   M...
1.11.0 – Novembro de 2010   Suporte mobile via    Zend_Http_UserAgent   API SimpleCloud via    Zend_Cloud
Arquitetura
Arquitetura
Arquitetura
Flexibilidade
Liberdade de Escolha
E daqui vamos para onde?
Revolução
Inevitável
Junte-se ou morra!
Evolução“A mutação é a chave para a nossa evolução.Ela nos permitiu evoluir de um organismounicelular à espécie dominante ...
Evolução
O foco do Zend Framework 2.0 é na melhoria daconsistência e performance.
Código Explícito   Não é isto:                class SoraniknatuController                extends Zend_Controller_Action  ...
Mágica   ouBruxaria?
Código Explícito   Código explícito é fácil de entender.   Código explícito é fácil de analisar.   Código explícito é f...
Melhorias incrementais
Passos de Bebê   Conversão de código dos prefixos de    fornecedor (por exemplo “Zend_Phaser”) para    namespaces do PHP ...
Reescrever somente onde faz          sentido
Mudanças na Infraestrutura
Namespaces
O problema   Nomes de classes muito grandes       Dificuldade de refatorar       Dificuldade de reter semântica com nom...
A solução   Cada arquivo de classe declara uma    namespace   Um namespace por arquivo   Qualquer classe usada que não ...
Exemplo de Namespacenamespace ZendEventManager;use ZendStdlibCallbackHandler;class EventManager implements EventCollection...
Usando Apelidosnamespace ZendMvc;use ZendStdlibDispatchable,ZendDiServiceLocator as Locator;class FrontController implemen...
Recomendação para MigraçãoImporte classes com o comandouse em vez de fazer chamadascom require_once em seucódigo!
Importando Classesuse Zend_Controller_Action as Controller;class PowerController extends Controller{                      ...
Nomeação   Todo código no projeto está no namespace    “Zend”   Cada componente define um namespace único   Classes den...
Exemplos de Nomeaçãonamespace ZendEventManager;class EventManager implements EventCollection{}
Interfaces
Interfaces   Interfaces são nomeadas de acordo com    nomes e adjetivos, e descrevem o que elas    provêem   Na maioria ...
Exemplo de Interfacesnamespace ZendSession;use Traversable, ArrayAccess, Serializable, Countable;interface Storage extends...
Implementação Concretanamespace ZendSessionStorage;use ArrayObject,ZendSessionStorage,ZendSessionException;class ArrayStor...
Exceções
O problema   Todas as exceções derivavam de uma classe    comum   Incapacidade de estender os tipos de exceção    semânt...
Abordagem ZF2   Zend_Exception foi eliminado   Cada componente define uma interface    Exception marcadora   Exceções c...
O que a solução provê   Captura tipos de exceções específicas   Captura tipos de exceções SPL   Captura exceções no nív...
Definições de Exceção                                   namespace ZendEventManager;                                   inte...
Capturando Exceçõesnamespace ZendEventManagerException;use ZendEventManagerException;try {$events->trigger(dom.quixote, $o...
Autocarregamento
O problema   Problemas de performance       Muitas classes são usadas apenas no momento        adequado e não devem ser ...
Abordagem ZF2   Chega de chamadas require_once!   Múltiplas abordagens de autocarregamento       Autocarregador via inc...
Autocarregamento estilo ZF1require_once Zend/Loader/StandardAutoloader.php;$loader = new ZendLoaderStandardAutoloader(arra...
Autocarregamento        Namespace/Prefixo ZF2require_once Zend/Loader/StandardAutoloader.php;$loader = new ZendLoaderStand...
Autocarregamento com Mapas de           Classes return array( GreenLanternHal => __DIR__ . /Lantern/Hal.php, );  require_o...
Mapas de Classes? Mas não dá         trabalho pra fazer?   Sim, dá trabalho. Mas nós temos uma    ferramenta, bin/classma...
Por que?   Mapas de Classes mostram 25% de melhoria    no carregador do ZF1 quando não é usada    aceleração.       E 60...
Fábrica de Autocarregadores   Com múltiplas estratégias vem a necessidade    por uma fábrica.   Escolha diversas estraté...
Exemplo de Fábrica de      Autocarregadoresrequire_once Zend/Loader/AutoloaderFactory.php;use ZendLoaderAutoloaderFactory;...
Quando posso migrar?   Você pode usar os autocarregadores e as    facilidades de geração dos mapas de classe do    ZF2......
Carregamento de Plugins
Terminologia   Para nossos propósitos, um “plugin” é qualquer    classe que é determinada em tempo de    execução.      ...
Plugins
O Problema   Variar abordagens para descobrir classes    plugin       Caminhos relativos para as classes chamadas      ...
Abordagem ZF2: o Agente de             Plugins   Interface de Localização de Plugins       Permite variar a implementaçã...
Interface de Localização de          Plugins   namespace ZendLoader;   interface ShortNameLocator   {   public function is...
Interface de Agente de Pluginsnamespace ZendLoader;interface Broker{public function load($plugin, array $options = null);p...
Como usar?   Crie um carregador de plugins padrão   Crie um agente de plugins padrão   Componha um agente dentro de sua...
Implementação do Localizador de           Plugins    namespace ZendView;    use ZendLoaderPluginClassLoader;    class Help...
Implementação do Agente de           Pluginsclass HelperBroker extends PluginBroker{protected $defaultClassLoader = ZendVi...
Compondo um Agenteuse ZendViewHelperLoader;class Sinestro{protected $broker;public function broker($spec = null, array $op...
Precedência dos Localizadores(Do menos para o mais específico)   Mapa definido no carregador de plugins    concreto   Ma...
Definindo Mapas Estáticosuse ZendViewHelperLoader;HelperLoader::addStaticMap(array(url=> KilowogHelperUrl,base_url => Proj...
Passando Mapas via           Configuraçãouse ZendViewHelperLoader;$config = array(url=> KilowogHelperUrl,base_url => Proje...
Passando Mapas para Mapas! use ZendViewHelperLoader, ZendLoaderPluginClassLoader; class HelperMap extends PluginClassLoade...
Estendendo Carregadoresuse ZendViewHelperLoader;class HelperMap extends HelperLoader{public function __construct($options ...
Passando Mapas via Agenteuse ZendViewHelperBroker;$broker = new HelperBroker(array(class_loader => array(class=> HelperMap...
Criando Mapas Manualmenteuse ZendViewHelperLoader;$loader = new HelperLoader();$loader->registerPlugin(url, KilowogHelperU...
Gerenciando Plugins via Agente   Por padrão, o carregador é consultado para um    nome de classe, e instancia a classe co...
Registrando um Plugin com o          Agenteuse KilowogHelperUrl;// Assume:// - $request == objeto Request// - $router == o...
E sobre o carregamento tardio?   Frequentemente você precisa configurar    plugins   Mas você quer uma instância só quan...
LazyLoadingBroker Interfacenamespace ZendLoader;interface LazyLoadingBroker extends Broker{public function registerSpec($n...
Usando LazyLoadingBroker   Registra “especificações” com o agente   Quando o plugin é requisitado, as opções    fornecid...
Usando LazyLoadingBroker$broker->registerSpec(url, array($request, $router));$broker->registerSpecs(array(url => array($re...
Usando LazyLoadingBroker via         Configuraçãouse ZendViewHelperBroker;$config = array(specs => array(url => array($req...
E ainda tem mais!
Novos Componentes
E Componentes Poderosos!
Novos Componentes   ZendEventManager   ZendDi
EventManager
O Problema   Como nós introduzimos pontos de log/debug    no código do framework?   Como nós permitimos que os usuários ...
O Problema   Como permitirmos que os usuários manipulem    a ordem na qual plugins, filtros de    interceptação, eventos,...
Solução: Programação Orientada          a Aspectos   O código define vários “aspectos” que podem    ser interessantes obs...
Requisitos   Projeto que seja razoavelmente fácil de    entender.   Permitir anexar manipuladores de forma    estática o...
Requisitos   Projeto que seja razoavelmente fácil de    entender.   Permitir anexar manipuladores de forma    estática o...
Requisitos   Previsibilidade de argumentos passados para    manipuladores.   Habilidade de anexar a muitos componentes  ...
Solução: Observador de Sujeitos   Prós       Simples de entender       Interfaces SPL são bem conhecidas (mas        li...
Solução: Publicador/Sobrescritor          de Eventos   Prós       Sobrescrita de notificações arbitrárias       Tipicam...
Solução: Publicador/Sobrescritor     de Eventos (PubSub)   Contras       Frequentemente, precisa testar o evento forneci...
Pausa para esclarecimento   boilerplate é o termo usado para descrever    seções de código que foram incluídas em    muit...
Solução: SignalSlots   Prós       Conceito bem conhecido nos círculos de Ciência da        Computação       O código em...
Solução: SignalSlots   Contras       Esse palavreado não é bem conhecido entre        programadores PHP.       Argument...
Filtros de Interceptação   Prós       Similar às soluções anteriores, exceto que cada        manipulador recebe a cadeia...
Filtros de Interceptação   Contras       Algumas vezes é difícil acompanhar fluxos de        trabalho complexos.       ...
Mas qual asolução afinal?
Nenhuma!
Todas!
Combinação                               de Poderes                                            LinkaWheeler Gi            ...
ZF2: EventManager Component   A cereja do bolo de cada solução, PubSub,    SignalSlot, e Filtros de Interceptação, para  ...
Interface EventCollectionnamespace ZendEventManager;use ZendStdlibCallbackHandler;interface EventCollection{public functio...
Disparando Eventosuse ZendEventManagerEventManager;$events = new EventManager();$events->trigger($eventName, $object, $par...
CallbackHandler$handler = $events->attach(algum-evento, function($e) use($log) {$event= $e->getName();$context = get_class...
Callback Handler com Prioridade$handler = $events->attach(algum-evento, function($e) use($log) {/* o mesmo que o anterior ...
Interrompendo a Execução:        Testando Resultados$results = $events->triggerUntil(algum-evento, $o,$argv,function($resu...
Interrompendo a Execução: via          Manipuladores$events->attach(algum-evento, function($e) {$result = new Result;$e->s...
Compondo um EventManageruse ZendEventManagerEventCollection as Events,ZendEventManagerEventManager;class Arisia{protected ...
Usando um Trait!use ZendEventManagerEventCollection as Events,ZendEventManagerEventManager;trait Eventful{public function ...
Conectando Manipuladores       Estaticamenteuse ZendEventManagerStaticEventManager;$events = StaticEventManager::getInstan...
Recomendações   Nomeie seus eventos usando __FUNCTION__       Se disparar múltiplos eventos no mesmo método,        sufi...
Injeção de Dependência (DI)
O Que é Injeção de Dependência?   Muito simples: definir modos de passar    dependências para dentro de um objeto.       ...
Então porque as pessoas tem            medo disso?   Porque elas não fazem isso.   Elas temem os Conteineres de Injeção ...
O Que é um Conteiner de Injeção        de Dependência  Colocando de forma       simples:Um grafo de objetos para  mapear r...
Grafos
Novamente, por que as pessoas     tem medo disso?   Porque parece mágica!
Objeto com Dependênciasnamespace TomarreHelper;class Url{public function __construct(Request $request){$this->request = $r...
Outro Objeto com Dependências     namespace mwopMvc;     class Router     {     public function addRoute(Route $route)    ...
Agarrando um Objeto e Usando-o$urlHelper = $di->get(url-helper);echo $url->generate(/css/site.css);echo $url->generate(arr...
As Questões   Como eu posso estar certo se eu tenho minhas    dependências?       Você as define explicitamente.       ...
As Questões   Se eu chamar $object = new Salaak(), como eu    forço o uso de diferentes dependências?       Chamar new n...
Por que usar um?   Se a instanciação de seus objetos não está    debaixo de seu controle direto (por exemplo,    controla...
Abordagem ZF2   Padronizar em uma interface de localizador de    serviços.   Prover uma solução DI performática, e integ...
Interface para Localizador de           Serviçosnamespace ZendDi;interface ServiceLocation{public function set($name, $ser...
Interface para Injetor de            Dependênciasnamespace ZendDi;interface DependencyInjection{public function get($name,...
Definiçõesnamespace ZendDi;interface DependencyDefinition{public function __construct($className);public function getClass...
Referênciasnamespace ZendDi;interface DependencyReference{public function __construct($serviceName);public function getSer...
Definição de Classeuse ZendDiDefinition,ZendDiReference;$mongo = new Definition(Mongo);$mongoDB = new Definition(MongoDB);...
Injeção por Modificadoruse ZendDiDefinition,ZendDiReference;$service = new Definition(mwopServiceResources);$service->addM...
Fazendo mais Rápido   Especificar mapas de parâmetros de construtor    em definições.   Gerar localizadores de serviço a...
Mapas de Parâmetros$mongoDB->setParam(conn, new Reference(mongo))->setParam(name, test)->setParamMap(array(conn => 0,name ...
Gerando um Localizador de       Serviços a partir de DIuse ZendDiContainerBuilder as DiBuilder;$builder = new DiBuilder($i...
Exemplo de um localizador           geradouse ZendDiDependencyInjectionContainer;class AppContext extends DependencyInject...
Usando um localizador gerado$context = new AppContext();$request = $context->get(request);// O mesmo que usar um localizad...
Fazendo mais simples ainda   Use arquivos de configuração   Você pode usar qualquer formato suportado    por ZendConfig:...
Exemplo de configuração com           JSON{"production": { "definitions": [{ "class": "Mongo" },{ "class": "MongoDB","para...
Quais são os casos de uso no                ZF2?   Um grandão.Tirar os controladores  MVC do conteiner
Um Controlador de Açãonamespace BlogController;class Entry implements Dispatchable{public function setResource(Resource $r...
O Controlador Frontalclass FrontController implements Dispatchable{public function __construct(DependencyInjection $di){$t...
Benefícios de usar DI deste modo   Performance   Desacoplamento de código   Simplificação do código do controlador
E vem mais por aí   Compilação na primeira execução.   Ferramentas para vasculhar classes ou    namespaces para construi...
Padrões MVC
Padrões MVC
Os Problemas   Como os controladores obtém dependências?   Como nós acomodamos diferentes padrões de    controladores?  ...
Os Problemas   Como nós podemos melhorar o uso de    componentes do servidor dentro do MVC?   Como nós podemos fazer o M...
A estrutura básica de umaaplicação web é a de um       ciclo de vida  Requisição/Resposta
A interface Dispatchablenamespace ZendStdlib;interface Dispatchable{public function dispatch(Request $request, Response $r...
Requisição e Resposta   Tanto a Requisição quanto a Resposta    simplesmente agregam metadados e conteúdo.   A Resposta ...
Qualquer Dispatchable pode           anexar ao MVCDispatchable é simplesmenteuma formalização do padrão deprojeto Command....
Um protótipo simples de um            Controlador Frontalpublic function dispatch(Request $request, Response $response = n...
Contexto Temporal   Quando esta apresentação foi finalizada, o    último release do Zend Framework 1 era o    1.11.11 e o...
Mais informações   http://framework.zend.com   https://github.com/zendframework/zf2   www.fgsl.eti.br       Aguarde......
O que esperar do Zend Framework 2
Próximos SlideShares
Carregando em…5
×

O que esperar do Zend Framework 2

5.407 visualizações

Publicada em

Novidades do Zend Framework 2. Palestra proferida na PHP Conference Brasil 2011.

Publicada em: Tecnologia
0 comentários
4 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
5.407
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2
Ações
Compartilhamentos
0
Downloads
86
Comentários
0
Gostaram
4
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

O que esperar do Zend Framework 2

  1. 1. Existe uma coisa que um programador PHPnão pode ter... MEDO!
  2. 2. Advertência Alguns exemplos de código são exemplos de como implementar construções com Zend Framework 2 e não do Zend Framework 2. Alguns exemplos fazem uso de construções disponíveis apenas no PHP 5.4.
  3. 3. Advertência Esta apresentação não visa saciar sua sede de conhecimento, mas deixar você sedento por ele.
  4. 4. O que esperar do Zend Framework 2 Flávio Gomes da Silva Lisboa www.fgsl.eti.br @fgsl
  5. 5. Inspirador Inspirado Desde 2008 capacitando profissionais em Zend Framework @eminetto @fgslESGOTADO ESGOTADO
  6. 6. Uma Breve História do ZF Flávio Gomes da Silva Lisboa
  7. 7. A Gênese Outubro de 2005: o projeto é anunciado Março de 2006: primeiro release público, 0.1.0 Final de 2006: Reescrita do MVC
  8. 8. 1.0.0, julho de 2007 Primeiro release estável Sistema básico de MVC, com plugins, action helpers, renderização automatizada, etc. Muitos consumidores de APIs de web services Classes servidoras para XML-RPC e REST.
  9. 9. 1.5.0 – Março de 2008 Primeiro release menor Zend_Form Zend_Layout Sistema de view helper ciente do layout Layout content View content
  10. 10. 1.6.0 – Setembro de 2008 Integração com Dojo Zend_Test: extensão PHPUnit para controladores Action helper ContextSwitch HTML JSON XML
  11. 11. 1.7.0 – Novembro de 2008 Suporte à AMF Melhorias de performance
  12. 12. 1.8.0 – Abril de 2009 Zend_Tool Zend_Application AMPLAMENTE USADO! Matthew OPhinney, ZF Leader e autor do conteúdo no qual esta apresentação se baseia
  13. 13. 1.9.0 – Agosto de 2009 Zend_Feed_Reader Suporte/compatibilidade com PHP 5.3 Adições levadas pela comunidade Início da caça mensal a bugs
  14. 14. 1.10.0 – Janeiro de 2009 Integração de ControllerTestCase com Zend_Application Adição de Zend_Feed_Writer Mudanças na documentação: adoção do PhD para renderizar o manual do usuário, introdução do sistema de comentário e a seção “Learning Zend Framework”
  15. 15. 1.11.0 – Novembro de 2010 Suporte mobile via Zend_Http_UserAgent API SimpleCloud via Zend_Cloud
  16. 16. Arquitetura
  17. 17. Arquitetura
  18. 18. Arquitetura
  19. 19. Flexibilidade
  20. 20. Liberdade de Escolha
  21. 21. E daqui vamos para onde?
  22. 22. Revolução
  23. 23. Inevitável
  24. 24. Junte-se ou morra!
  25. 25. Evolução“A mutação é a chave para a nossa evolução.Ela nos permitiu evoluir de um organismounicelular à espécie dominante do planeta. Oprocesso é lento, normalmente leva milhares emilhares de anos. Mas em algumas centenas demilênios a evolução dá um salto.”
  26. 26. Evolução
  27. 27. O foco do Zend Framework 2.0 é na melhoria daconsistência e performance.
  28. 28. Código Explícito Não é isto: class SoraniknatuController extends Zend_Controller_Action { public function useTheRingAction() { $this->view->object = imagination; } } Onde isso Quando E os está ocorre a layouts? definido? renderização?
  29. 29. Mágica ouBruxaria?
  30. 30. Código Explícito Código explícito é fácil de entender. Código explícito é fácil de analisar. Código explícito é fácil de manter.
  31. 31. Melhorias incrementais
  32. 32. Passos de Bebê Conversão de código dos prefixos de fornecedor (por exemplo “Zend_Phaser”) para namespaces do PHP 5.3 Refatoração das exceções Somente autoload Melhoria e padronização do sistema de plugins
  33. 33. Reescrever somente onde faz sentido
  34. 34. Mudanças na Infraestrutura
  35. 35. Namespaces
  36. 36. O problema Nomes de classes muito grandes  Dificuldade de refatorar  Dificuldade de reter semântica com nomes mais curtosZend_Form_Decorator_Marker_File_Interface
  37. 37. A solução Cada arquivo de classe declara uma namespace Um namespace por arquivo Qualquer classe usada que não estiver no namespace atual (ou em um subnamespace) é importada e tipicamente apelidada A resolução global é desencorajada, exceto no caso de classes referenciadas em strings.
  38. 38. Exemplo de Namespacenamespace ZendEventManager;use ZendStdlibCallbackHandler;class EventManager implements EventCollection{/* ... */}
  39. 39. Usando Apelidosnamespace ZendMvc;use ZendStdlibDispatchable,ZendDiServiceLocator as Locator;class FrontController implements Dispatchable{public function __construct(Locator $locator){$this->serviceLocator = $locator;}}
  40. 40. Recomendação para MigraçãoImporte classes com o comandouse em vez de fazer chamadascom require_once em seucódigo!
  41. 41. Importando Classesuse Zend_Controller_Action as Controller;class PowerController extends Controller{ ZF1} Como ficará:use ZendControllerAction as Controller;class PowerController extends Controller{ ZF2}
  42. 42. Nomeação Todo código no projeto está no namespace “Zend” Cada componente define um namespace único Classes dentro de um componente residem naquele namespace ou em um subnamespace Tipicamente, uma classe nomeada de acordo com o componente é a classe gateway.
  43. 43. Exemplos de Nomeaçãonamespace ZendEventManager;class EventManager implements EventCollection{}
  44. 44. Interfaces
  45. 45. Interfaces Interfaces são nomeadas de acordo com nomes e adjetivos, e descrevem o que elas provêem Na maioria dos casos, implementações concretas interfaces residem em um subnamespace nomeado de acordo com a interface Um paradigma Orientado a Contrato mais forte
  46. 46. Exemplo de Interfacesnamespace ZendSession;use Traversable, ArrayAccess, Serializable, Countable;interface Storage extends Traversable, ArrayAccess, Serializable,Countable{}
  47. 47. Implementação Concretanamespace ZendSessionStorage;use ArrayObject,ZendSessionStorage,ZendSessionException;class ArrayStorage extends ArrayObject implements Storage{/* ... */}
  48. 48. Exceções
  49. 49. O problema Todas as exceções derivavam de uma classe comum Incapacidade de estender os tipos de exceção semânticas oferecidas na SPL Estratégias de captura limitadas Forte dependência para cada e todos os componenentes
  50. 50. Abordagem ZF2 Zend_Exception foi eliminado Cada componente define uma interface Exception marcadora Exceções concretas residem em um subnamespace Exception, e estendem exceções SPL
  51. 51. O que a solução provê Captura tipos de exceções específicas Captura tipos de exceções SPL Captura exceções no nível do componente Captura baseada no tipo de exceção global
  52. 52. Definições de Exceção namespace ZendEventManager; interface Exception { }namespace ZendEventManagerException;use ZendEventManagerException;class InvalidArgumentException extends InvalidArgumentExceptionimplements Exception{}
  53. 53. Capturando Exceçõesnamespace ZendEventManagerException;use ZendEventManagerException;try {$events->trigger(dom.quixote, $object);} catch (InvalidArgumentException $e) {} catch (Exception $e) {} catch (InvalidArgumentException $e) {} catch (Exception $e) {}
  54. 54. Autocarregamento
  55. 55. O problema Problemas de performance  Muitas classes são usadas apenas no momento adequado e não devem ser carregadas até que seja necessário. A falta de chamadas require_once leva a erros.
  56. 56. Abordagem ZF2 Chega de chamadas require_once! Múltiplas abordagens de autocarregamento  Autocarregador via include_path estilo ZF1  Autocarregamento pelo namespace / prefixo do fornecedor  Autocarregamento por Mapa de Classes
  57. 57. Autocarregamento estilo ZF1require_once Zend/Loader/StandardAutoloader.php;$loader = new ZendLoaderStandardAutoloader(array(fallback_autoloader => true,));$loader->register(); EX EM PL O
  58. 58. Autocarregamento Namespace/Prefixo ZF2require_once Zend/Loader/StandardAutoloader.php;$loader = new ZendLoaderStandardAutoloader();$loader->registerNamespace(My, __DIR__ . /../library/My)->registerPrefix(Fgsl_, __DIR__ . /../library/Fgsl);$loader->register(); EX EM PL O
  59. 59. Autocarregamento com Mapas de Classes return array( GreenLanternHal => __DIR__ . /Lantern/Hal.php, ); require_once Zend/Loader/ClassMapAutoloader.php; $loader = new ZendLoaderClassMapAutoloader(); $loader->registerAutoloadMap(__DIR__ . /../library/.classmap.php); $loader->register();
  60. 60. Mapas de Classes? Mas não dá trabalho pra fazer? Sim, dá trabalho. Mas nós temos uma ferramenta, bin/classmap_generator.php E o uso é trivial:prompt> cd your/library prompt> php /path/to/classmap_generator.php -w A execução desse script cria o Mapa de Classes em .classmap.php
  61. 61. Por que? Mapas de Classes mostram 25% de melhoria no carregador do ZF1 quando não é usada aceleração.  E 60-85% quando um cache de opcode está em uso. O emparelhamento namespaces/prefixos com caminhos especificados mostra um ganho de 10% sem aceleração.  E 40% de melhoria quando uma cache de opcode é usado.
  62. 62. Fábrica de Autocarregadores Com múltiplas estratégias vem a necessidade por uma fábrica. Escolha diversas estratégias:  Mapa de Classes para pesquisa mais rápida  Caminhos namespace/prefixo para código comum  Autocarregador de reserva estilo ZF1/PSR-0 para desenvolvimento PSR: PHP Specification Request
  63. 63. Exemplo de Fábrica de Autocarregadoresrequire_once Zend/Loader/AutoloaderFactory.php;use ZendLoaderAutoloaderFactory;AutoloaderFactory::factory(array(ZendLoaderClassMapAutoloader => array(__DIR__ . /../library/.classmap.php,__DIR__ . /../application/.classmap.php,),ZendLoaderStandardAutoloader => array(namespaces => array(Zend => __DIR__ . /../library/Zend,),fallback_autoloader => true,),));
  64. 64. Quando posso migrar? Você pode usar os autocarregadores e as facilidades de geração dos mapas de classe do ZF2... hoje! Pode começar a migração!
  65. 65. Carregamento de Plugins
  66. 66. Terminologia Para nossos propósitos, um “plugin” é qualquer classe que é determinada em tempo de execução.  Auxiliares de Controle e Visão  Adaptadores  Filtros e Validadores
  67. 67. Plugins
  68. 68. O Problema Variar abordagens para descobrir classes plugin  Caminhos relativos para as classes chamadas  Pilhas prexifo-caminho (mais comum)  Modificadores para indicar classes A abordagem mais comum é terrível  Má performance  Difícil de depurar  Sem caching de plugins descobertos
  69. 69. Abordagem ZF2: o Agente de Plugins Interface de Localização de Plugins  Permite variar a implementação de pesquisa de plugins Interface de Agente de Plugins  Compõe um Localizador de Plugins
  70. 70. Interface de Localização de Plugins namespace ZendLoader; interface ShortNameLocator { public function isLoaded($name); public function getClassName($name); public function load($name); }
  71. 71. Interface de Agente de Pluginsnamespace ZendLoader;interface Broker{public function load($plugin, array $options = null);public function getPlugins();public function isLoaded($name);public function register($name, $plugin);public function unregister($name);public function setClassLoader(ShortNameLocator $loader);public function getClassLoader();}
  72. 72. Como usar? Crie um carregador de plugins padrão Crie um agente de plugins padrão Componha um agente dentro de sua classe Opcionalmente, defina configuração estática Opcionalmente, passe a configuração de agente e carregador Opcionalmente, registre plugins com o localizador ou o agente
  73. 73. Implementação do Localizador de Plugins namespace ZendView; use ZendLoaderPluginClassLoader; class HelperLoader extends PluginClassLoader { /** * @var array Pre-aliased view helpers */ protected $plugins = array( action => ZendViewHelperAction, base_url => ZendViewHelperBaseUrl, /* ... */ ); }
  74. 74. Implementação do Agente de Pluginsclass HelperBroker extends PluginBroker{protected $defaultClassLoader = ZendViewHelperLoader;public function load($plugin, array $options = null){$helper = parent::load($plugin, $options);if (null !== ($view = $this->getView())) {$helper->setView($view);}return $helper;}protected function validatePlugin($plugin){if (! $plugin instanceof Helper) {throw new InvalidHelperException();}return true;}}
  75. 75. Compondo um Agenteuse ZendViewHelperLoader;class Sinestro{protected $broker;public function broker($spec = null, array $options = array()){if ($spec instanceof Broker) {$this->broker = $spec;return $spec;} elseif (null === $this->broker) {$this->broker = new PluginBroker();}if (null === $spec) {return $this->broker;} elseif (!is_string($spec)) {throw new Exception();}return $this->broker->load($spec, $options);}}
  76. 76. Precedência dos Localizadores(Do menos para o mais específico) Mapa definido no carregador de plugins concreto Mapas estáticos ( o registro mais recente tem precedência) Mapeamento passado via instanciação Mapeamento explícito provido programaticamente
  77. 77. Definindo Mapas Estáticosuse ZendViewHelperLoader;HelperLoader::addStaticMap(array(url=> KilowogHelperUrl,base_url => ProjectHelperBaseUrl,));$loader = new HelperLoader();$class = $loader->load(url); // "KilowogHelperUrl"
  78. 78. Passando Mapas via Configuraçãouse ZendViewHelperLoader;$config = array(url=> KilowogHelperUrl,base_url => ProjectHelperBaseUrl,);$loader = new HelperLoader($config);$class = $loader->load(url); // "KilowogHelperUrl"
  79. 79. Passando Mapas para Mapas! use ZendViewHelperLoader, ZendLoaderPluginClassLoader; class HelperMap extends PluginClassLoader { protected $plugins = array( url => KilowogHelperUrl, base_url => ProjectHelperBaseUrl, ); } $helpers = new HelperMap(); $loader = new HelperLoader($helpers); $class = $loader->load(url); // "KilowogHelperUrl"
  80. 80. Estendendo Carregadoresuse ZendViewHelperLoader;class HelperMap extends HelperLoader{public function __construct($options = null){// Adiciona e/ou sobrescreve o mapa doHelperLoader$this->registerPlugins(array(url=> KilowogHelperUrl,base_url => ProjectHelperBaseUrl,));parent::__construct($options);}}$helpers = new HelperMap();$class= $loader->load(url); // "KilowogHelperUrl"
  81. 81. Passando Mapas via Agenteuse ZendViewHelperBroker;$broker = new HelperBroker(array(class_loader => array(class=> HelperMap,options => array(base_url => AppHelperBaseUrl,),),));$plugin = $broker->load(base_url); // "AppHelperBaseUrl"
  82. 82. Criando Mapas Manualmenteuse ZendViewHelperLoader;$loader = new HelperLoader();$loader->registerPlugin(url, KilowogHelperUrl)->registerPlugins(array(base_url => ProjectHelperBaseUrl,));$class = $loader->load(url); // "KilowogHelperUrl"
  83. 83. Gerenciando Plugins via Agente Por padrão, o carregador é consultado para um nome de classe, e instancia a classe com os argumentos dados Opcionalmente, você pode alimentar o agente, registrando objetos plugins manualmente sob um dado nome
  84. 84. Registrando um Plugin com o Agenteuse KilowogHelperUrl;// Assume:// - $request == objeto Request// - $router == objeto Router// - $broker == HelperBroker$url = new Url($request, $router);$broker->registerPlugin(url, $url); // OU:$broker->registerPlugins(array(url => $url,));$url = $broker->load(url); // === $url acima
  85. 85. E sobre o carregamento tardio? Frequentemente você precisa configurar plugins Mas você quer uma instância só quando ela for realmente requisitada É aí que entra ZendLoaderLazyLoadingBroker
  86. 86. LazyLoadingBroker Interfacenamespace ZendLoader;interface LazyLoadingBroker extends Broker{public function registerSpec($name, array $spec = null);public function registerSpecs($specs);public function unregisterSpec($name);public function getRegisteredPlugins();public function hasPlugin($name);}
  87. 87. Usando LazyLoadingBroker Registra “especificações” com o agente Quando o plugin é requisitado, as opções fornecidas serão usadas a menos que novas opções sejam passadas De todas as outras maneiras, ele comporta-se como outros agentes, incluindo a permissão do registro explícito de plugins
  88. 88. Usando LazyLoadingBroker$broker->registerSpec(url, array($request, $router));$broker->registerSpecs(array(url => array($request, $router),));if (!$broker->hasPlugin(url)) {// sem especificação!}$plugins = $broker->getRegisteredPlugins(); // array(url)$url = $broker->load(url); // Com $request, $router éinjetado
  89. 89. Usando LazyLoadingBroker via Configuraçãouse ZendViewHelperBroker;$config = array(specs => array(url => array($request, $router),),);$broker = new HelperBroker($config);$url= $broker->load(url); // Com $request, $router éinjetado
  90. 90. E ainda tem mais!
  91. 91. Novos Componentes
  92. 92. E Componentes Poderosos!
  93. 93. Novos Componentes ZendEventManager ZendDi
  94. 94. EventManager
  95. 95. O Problema Como nós introduzimos pontos de log/debug no código do framework? Como nós permitimos que os usuários introduzam caching sem necessidade de estender o código do framework? Como nós permitimos que os usuários introduzam validação, filtragem, verificações de controle de acesso, etc., sem necessariamente estender o código do framework?
  96. 96. O Problema Como permitirmos que os usuários manipulem a ordem na qual plugins, filtros de interceptação, eventos, etc., são disparados. Como nós podemos prover ferramentas para o código do usuário trabalhe em prol das questões anteriores?
  97. 97. Solução: Programação Orientada a Aspectos O código define vários “aspectos” que podem ser interessantes observar e/ou anexar a partir de um consumidor. Basicamente, todas as soluções que examinaremos podem ser usadas para implementar POA em um código base. www.fgsl.eti.br Palestras
  98. 98. Requisitos Projeto que seja razoavelmente fácil de entender. Permitir anexar manipuladores de forma estática ou por instância, preferencialmente de ambas as formas. Preferencialmente enquanto reter o estado não-global ou permitir sobrescrita. Permitir interrupção da execução Permitir a priorização de manipuladores
  99. 99. Requisitos Projeto que seja razoavelmente fácil de entender. Permitir anexar manipuladores de forma estática ou por instância, preferencialmente de ambas as formas. Preferencialmente enquanto reter o estado não-global ou permitir sobrescrita. Permitir interrupção da execução Permitir a priorização de manipuladores
  100. 100. Requisitos Previsibilidade de argumentos passados para manipuladores. Habilidade de anexar a muitos componentes emissores de eventos de uma vez.
  101. 101. Solução: Observador de Sujeitos Prós  Simples de entender  Interfaces SPL são bem conhecidas (mas limitadas) Contras  Tipicamente, não pode interromper a execução de observadores remanescentes  Requer um sistema para cada componente e/ou classe  Tipicamente, sem habilidade para priorizar manipuladores
  102. 102. Solução: Publicador/Sobrescritor de Eventos Prós  Sobrescrita de notificações arbitrárias  Tipicamente por componente + uso global; em muitas linguagens, um único agregador global  Paradigma bem-conhecido na programação de interfaces com o usuário (pense em Javascript)  Tende a ser um Turing completo
  103. 103. Solução: Publicador/Sobrescritor de Eventos (PubSub) Contras  Frequentemente, precisa testar o evento fornecido para garantir que você pode manipulá-lo.  Uso global implica em agregação estática e/ou dependências estáticas.  … mas o uso por componente implica em um boilerplate para compor em cada classe se ele for usado.  Tipicamente, sem habilidade para priorizar manipuladores. Falaremos mais sobre isso mais tarde...
  104. 104. Pausa para esclarecimento boilerplate é o termo usado para descrever seções de código que foram incluídas em muitos lugares com pouca ou nenhuma alteração.
  105. 105. Solução: SignalSlots Prós  Conceito bem conhecido nos círculos de Ciência da Computação  O código emite sinais, que são interceptados por slots (vulgos manipuladores)  Tipicamente, compõe um gerenciador de sinais em uma classe, mas pode ser integrado com um gerenciador global também  Geralmente tem algumas habilidades para priorizar manipuladores
  106. 106. Solução: SignalSlots Contras  Esse palavreado não é bem conhecido entre programadores PHP.  Argumentos irão variar entre sinais.  Os mesmos problemas com composição por classe e uso estático como vemos em sistemas de eventos.
  107. 107. Filtros de Interceptação Prós  Similar às soluções anteriores, exceto que cada manipulador recebe a cadeia de filtros como um argumento, e é responsável por chamar o próximo na cadeia.  Frequentemente, o “trabalho” inteiro de um método é simplesmente um executar um filtro.  Dependendo do projeto, pode permitir acesso global/estático.
  108. 108. Filtros de Interceptação Contras  Algumas vezes é difícil acompanhar fluxos de trabalho complexos.  Os mesmos problemas com composição por classe e uso estático como vemos em sistemas de evento.  É fácil esquecer de invocar o próximo filtro na cadeia.  Tipicamente, sem habilidade de priorizar filtros.
  109. 109. Mas qual asolução afinal?
  110. 110. Nenhuma!
  111. 111. Todas!
  112. 112. Combinação de Poderes LinkaWheeler Gi Ma-Ti Kwame
  113. 113. ZF2: EventManager Component A cereja do bolo de cada solução, PubSub, SignalSlot, e Filtros de Interceptação, para prover uma solução compreensiva. Não pode resolver completamente os problemas de composição/uso estático. Nós podemos resolver o problema da composição no PHP 5.4 com Traits. Há formas elegantes de manipular o uso estático.
  114. 114. Interface EventCollectionnamespace ZendEventManager;use ZendStdlibCallbackHandler;interface EventCollection{public function trigger($event, $context, $argv = array());public function triggerUntil($event, $context, $argv, $callback);public function attach($event, $callback, $priority = 1);public function detach(CallbackHandler $handle);public function getEvents();public function getHandlers($event);public function clearHandlers($event);}
  115. 115. Disparando Eventosuse ZendEventManagerEventManager;$events = new EventManager();$events->trigger($eventName, $object, $params);/* Onde: * - $eventName é o nome do evento; geralmente o nome do eventoatual** - $object é o objeto que está disparando o evento* - $params são os parâmetros que o manipulador pode precisarpara ter acesso,geralmente os argumentos do método**/
  116. 116. CallbackHandler$handler = $events->attach(algum-evento, function($e) use($log) {$event= $e->getName();$context = get_class($e->getTarget());$params = json_encode($e->getParams());$log->info(sprintf("%s: %s: %s", $event, $context, $params));});
  117. 117. Callback Handler com Prioridade$handler = $events->attach(algum-evento, function($e) use($log) {/* o mesmo que o anterior */}, 100); // Priorize! (números altos ganham)
  118. 118. Interrompendo a Execução: Testando Resultados$results = $events->triggerUntil(algum-evento, $o,$argv,function($result) {return ($result instanceof SomeType);});if ($results->stopped()) {return $results->last();}
  119. 119. Interrompendo a Execução: via Manipuladores$events->attach(algum-evento, function($e) {$result = new Result;$e->stopPropagation(true);return $result;});$results = $events->trigger(algum-evento, $object,$params);if ($results->stopped()) {return $results->last();}
  120. 120. Compondo um EventManageruse ZendEventManagerEventCollection as Events,ZendEventManagerEventManager;class Arisia{protected $events;public function events(Events $events = null){if (null !== $events) {$this->events = $events;} elseif (null === $this->events) {$this->events = new EventManager(__CLASS__);}return $this->events;}public function doSomething($param1, $param2){$params = compact(param1, param2);$this->events()->trigger(__FUNCTION__, $this, $params);}}
  121. 121. Usando um Trait!use ZendEventManagerEventCollection as Events,ZendEventManagerEventManager;trait Eventful{public function events(Events $events = null){if (null !== $events) {$this->events = $events;} elseif (null === $this->events) {$this->events = new EventManager(__CLASS__);}return $this->events;}}class Arisia{use Eventful;protected $events;}
  122. 122. Conectando Manipuladores Estaticamenteuse ZendEventManagerStaticEventManager;$events = StaticEventManager::getInstance();$events->connect(Arisia, algum-evento, function($e) {/* ... */});
  123. 123. Recomendações Nomeie seus eventos usando __FUNCTION__  Se disparar múltiplos eventos no mesmo método, sufixe com um “.(pre|pos|etc.)” Forneça para o construtor do EventManager tanto o nome da classe quanto um ou mais nomes de “serviços”, para fazer anexações estáticas mais semânticas.  Isso permite que um único callback ouça muitos componentes!
  124. 124. Injeção de Dependência (DI)
  125. 125. O Que é Injeção de Dependência? Muito simples: definir modos de passar dependências para dentro de um objeto. namespace TomarreHelper; class Url { public function __construct(Request $request) { $this->request = $request; } public function setRouter(Router $router) { $this->router = $router; } }
  126. 126. Então porque as pessoas tem medo disso? Porque elas não fazem isso. Elas temem os Conteineres de Injeção de Dependência.
  127. 127. O Que é um Conteiner de Injeção de Dependência Colocando de forma simples:Um grafo de objetos para mapear relações de dependência entre objetos.
  128. 128. Grafos
  129. 129. Novamente, por que as pessoas tem medo disso? Porque parece mágica!
  130. 130. Objeto com Dependênciasnamespace TomarreHelper;class Url{public function __construct(Request $request){$this->request = $request;}public function setRouter(Router $router){$this->router = $router;}}
  131. 131. Outro Objeto com Dependências namespace mwopMvc; class Router { public function addRoute(Route $route) { $this->routes->push($route); } }
  132. 132. Agarrando um Objeto e Usando-o$urlHelper = $di->get(url-helper);echo $url->generate(/css/site.css);echo $url->generate(array(id => $id), array(name =>blog));
  133. 133. As Questões Como eu posso estar certo se eu tenho minhas dependências?  Você as define explicitamente.  Você recupera o objeto via conteiner, o que garante que as definições são usadas. Onde eu defino essas coisas?  Programaticamente, via configuração, ou usando uma ferramenta.
  134. 134. As Questões Se eu chamar $object = new Salaak(), como eu forço o uso de diferentes dependências?  Chamar new não usa o conteiner. Na verdade, nada força você a usá-lo!
  135. 135. Por que usar um? Se a instanciação de seus objetos não está debaixo de seu controle direto (por exemplo, controladores), como você retém controle sobre suas dependências?  Acesso a dados diferente baseado no ambiente da aplicação.  Substituição de implementações mock/stub durante o teste.
  136. 136. Abordagem ZF2 Padronizar em uma interface de localizador de serviços. Prover uma solução DI performática, e integrá- la dentro de um localizador de serviços. Prover ferramentas para auxiliar na criação de definições de DI durante o desenvolvimento.
  137. 137. Interface para Localizador de Serviçosnamespace ZendDi;interface ServiceLocation{public function set($name, $service);public function get($name, array $params = null);}
  138. 138. Interface para Injetor de Dependênciasnamespace ZendDi;interface DependencyInjection{public function get($name, array $params = null);public function newInstance($name, array $params = null);public function setDefinitions($definitions);public function setDefinition(DependencyDefinition $definition, $serviceName = null);public function setAlias($alias, $serviceName);public function getDefinitions();public function getAliases();}
  139. 139. Definiçõesnamespace ZendDi;interface DependencyDefinition{public function __construct($className);public function getClass();public function setConstructorCallback($callback);public function getConstructorCallback();public function hasConstructorCallback();public function setParam($name, $value);public function setParams(array $params);public function setParamMap(array $map);public function getParams();public function setShared($flag = true);public function isShared();public function addTag($tag);public function addTags(array $tags);public function getTags();public function hasTag($tag);public function addMethodCall($name, array $args);public function getMethodCalls();}
  140. 140. Referênciasnamespace ZendDi;interface DependencyReference{public function __construct($serviceName);public function getServiceName();}
  141. 141. Definição de Classeuse ZendDiDefinition,ZendDiReference;$mongo = new Definition(Mongo);$mongoDB = new Definition(MongoDB);$mongoDB->setParam(conn, new Reference(mongo))->setParam(name, test);$coll = new Definition(MongoCollection);$coll->setParam(db, new Reference(mongodb))->setParam(name, resource);$di->setDefinitions(array(mongo=> $mongo,mongodb => $mongoDB,resource => $coll,));$resource = $di->get(resource);
  142. 142. Injeção por Modificadoruse ZendDiDefinition,ZendDiReference;$service = new Definition(mwopServiceResources);$service->addMethod(setResource, array(new Reference(resource)));$di->setDefinition(resources, $service);$resources = $di->get(resources);
  143. 143. Fazendo mais Rápido Especificar mapas de parâmetros de construtor em definições. Gerar localizadores de serviço a partir de um conteiner DI.
  144. 144. Mapas de Parâmetros$mongoDB->setParam(conn, new Reference(mongo))->setParam(name, test)->setParamMap(array(conn => 0,name => 1,));// Garante que os parâmetros estão em ordem, sem precisar// recorrer à API de reflexão
  145. 145. Gerando um Localizador de Serviços a partir de DIuse ZendDiContainerBuilder as DiBuilder;$builder = new DiBuilder($injector);$builder->setContainerClass(AppContext);$container = $builder->getCodeGenerator(__DIR__ . /../application/AppContext.php); // Retorna uma instância de ZendCodeGeneratorPhpPhpFile$container->write(); // Grava no disco
  146. 146. Exemplo de um localizador geradouse ZendDiDependencyInjectionContainer;class AppContext extends DependencyInjectionContainer{public function get($name, array $params = array()){switch ($name) {case request:case ZendHttpRequest:return $this->getZendHttpRequest();default:return parent::get($name, $params);}}public function getZendHttpRequest(){if (isset($this->services[ZendHttpRequest])) {return $this->services[ZendHttpRequest];}$object = new ZendHttpRequest();$this->services[ZendHttpRequest] = $object;return $object;}}
  147. 147. Usando um localizador gerado$context = new AppContext();$request = $context->get(request);// O mesmo que usar um localizador de serviços ouum conteiner DI!
  148. 148. Fazendo mais simples ainda Use arquivos de configuração Você pode usar qualquer formato suportado por ZendConfig:  INI  JSON  XML  YAML
  149. 149. Exemplo de configuração com JSON{"production": { "definitions": [{ "class": "Mongo" },{ "class": "MongoDB","params": {"conn": {"__reference": "mongocxn"},"name": "mwoptest"},"param_map": { "conn": 0, "name": 1 }},{ "class": "MongoCollection","params": {"db": {"__reference": "MongoDB"},"name": "entries"},"param_map": { "db": 0, "name": 1 }}], "aliases": {"mongocxn": "Mongo","mongo-collection-entries": "MongoCollection"}}}
  150. 150. Quais são os casos de uso no ZF2? Um grandão.Tirar os controladores MVC do conteiner
  151. 151. Um Controlador de Açãonamespace BlogController;class Entry implements Dispatchable{public function setResource(Resource $resource){$this->resource = $resource;}public function dispatch(Request $request, Response $response =null){/* ... */$entry = $this->resource->get($id);/* ... */}}
  152. 152. O Controlador Frontalclass FrontController implements Dispatchable{public function __construct(DependencyInjection $di){$this->di = $di;}public function dispatch(Request $request, Response $response =null){/* ... */$controller = $this->di->get($controllerName);$result = $controller->dispatch($request, $response);/* ... */}}
  153. 153. Benefícios de usar DI deste modo Performance Desacoplamento de código Simplificação do código do controlador
  154. 154. E vem mais por aí Compilação na primeira execução. Ferramentas para vasculhar classes ou namespaces para construir definições. Injeção de interface. … e mais coisas legais.
  155. 155. Padrões MVC
  156. 156. Padrões MVC
  157. 157. Os Problemas Como os controladores obtém dependências? Como nós acomodamos diferentes padrões de controladores?  E se se nós quisermos uma seleção de ações mais apurada, baseada em outros dados no ambiente de requisição?  E se quisermos passar argumentos para nomes de ações, ou argumentos pré-validados?  E se nós não gostarmos do sufixo “Action” nos métodos acionadores?  E se...
  158. 158. Os Problemas Como nós podemos melhorar o uso de componentes do servidor dentro do MVC? Como nós podemos fazer o MVC mais performático?
  159. 159. A estrutura básica de umaaplicação web é a de um ciclo de vida Requisição/Resposta
  160. 160. A interface Dispatchablenamespace ZendStdlib;interface Dispatchable{public function dispatch(Request $request, Response $response = null);}
  161. 161. Requisição e Resposta Tanto a Requisição quanto a Resposta simplesmente agregam metadados e conteúdo. A Resposta também tem a habilidade de enviar a si mesma. Variantes específicas de HTTP serão o núcleo do MVC.  Para prover conveniência em torno de variáveis superglobais, cookies e tarefas comuns tais como determinar os cabeçalhos Accept e Content-Type.
  162. 162. Qualquer Dispatchable pode anexar ao MVCDispatchable é simplesmenteuma formalização do padrão deprojeto Command. Controladores Servidores Qualquer coisa que você sonhar! Apenas implemente Dispatchable!
  163. 163. Um protótipo simples de um Controlador Frontalpublic function dispatch(Request $request, Response $response = null){$params = compact(request, response);$this->events()->trigger(__FUNCTION__ . .route.pre, $this,$params);$result = $this->getRouter()->route($request);if (!$result) {$result = array(controller => page, page => 404);}$params[routing] = (object) $result;$this->events()->trigger(__FUNCTION__ . .route.post, $params);$controller = $this->di->get($params[routing]->controller);if (!$controller instanceof Dispatchable) {$controller = new NotFoundController();}$result = $controller->dispatch($request, $response);$params[__RESULT__] = $result;$this->events()->trigger(__FUNCTION__ . .dispatch.post,$params);return $response;}
  164. 164. Contexto Temporal Quando esta apresentação foi finalizada, o último release do Zend Framework 1 era o 1.11.11 e o Zend Framework 2 estava na versão 2.0.0beta1.
  165. 165. Mais informações http://framework.zend.com https://github.com/zendframework/zf2 www.fgsl.eti.br  Aguarde... treinamentos de arquitetura, migração, e desenvolvimento.  Pra quem quer sair na frente, Mão na Massa MVC Zend Framework 2!  Coming soon 2012!

×